gpib_parser.c 114 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525
  1. #include "lpc176x.h"
  2. #include "usb_hardware.h"
  3. #ifdef USBTMC // #endif â êîíöå ôàéëà
  4. #include "utils.h"
  5. #include "../usbtmc/gpib_parser.h"
  6. #include "../usbtmc/gpib_parser_validators.h"
  7. #include "../usbtmc/gpib_parser_strutils.h"
  8. #include "../usbtmc/gpib_parser_numutils.h"
  9. #include "usb_enumeration.h"
  10. #include "../usbtmc/usbtmc.h"
  11. #include "../usbtmc/utilits.h"
  12. #include "usb_options.h"
  13. #include "options.h"
  14. #include "usb_application.h"
  15. #include "usb_proto.h"
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <stddef.h> // ptrdiff_t
  19. static char SCPIBParam[ MEMORY_SIZE_PARAMQUEUE ];
  20. // Ïàðñèíã GPIB êîììàíä. Êîììàíäû òèïà :COMMAND1:COMMAND2:COMMAND3 <DATA> ðàçáèâàþòñÿ íà îòäåëüíûå
  21. // êîììàíäû COMMAND1, COMMAND2, COMMAND3. Èçíà÷àëüíî, òðåáóåòñÿ îïðåäåëèòü, êàêèå êîììàíëû áóäóò ïîääåðæèâàòüñÿ.
  22. // Êàæäàÿ êîììàíäà ïðåäñòàâëÿåò ñîáîé íåêóþ ñòðóêòóðó äàííûõ, îïèñàííóþ íèæå (sScpiCommand_t). Îíà èìååò çàãîëîâîê,
  23. // òîåñòü ñîáñòâåííî èìÿ êîììàíäû, ñîêðàùåííîå èìÿ êîììàíäû, óêàçàòåëü íà ôóíêöèþ, êîòîðàÿ áóäåò âûïîëíåíà,
  24. // åñëè êîììàíäà ïðèíÿòà, è óêàçàòåëü íà ñïèñîê äî÷åðíèõ êîììàíä. Òàê, íàïðèìåð, êîììàíäà :SYSTem ìîæåò èìåòü
  25. // äâå äî÷åðíèå êîììàíäû INFO è VERsion. Äëÿ ïàðñèíãà ñòðîèòñÿ äåðåâî êîììàíä. Ñíà÷àëà íóæíî îáúÿâèòü êîðíåâóþ êîììàíäó,
  26. // êîòîðàÿ íå èìååò èìåíè, íî èìååò äî÷åðíèå êîììàíäû, òàê íàçûâàåìàÿ root êîììàíäà. ÏÐè íà÷àëå ðàçáîðà, êîììàíäû
  27. // áóäóò èçíà÷àëüíî èñêàòüñÿ èìåííî â äî÷åðíèõ êîììàíäàõ root. Äëÿ òîãî, ÷òîáû îáúÿâèòü root, âûçîâåì ôóíêöèþ
  28. // GPIB_InitializeCommand(sScpiCommand_t * Pointer, char * header, char *shortheader, TCmdParser_f function, unsigned int childcount )
  29. // ãäå Pointer - óêàçàòåëü íà âûäåëåííóþ ïîä ñòðóòóðó ïàìÿòü, header è shortheader óêàçàòåëè íà ñòðîêè, ñîäåðæàùèå
  30. // ïîëíîå è ñîêðàùåííûå èìåíà êîììàíäû ñîîòâåòñâåííî (îíè ìîãóò áûòü ðàçìåùåíû â ñåêöèè êîäà), function - óêàçàòåëü íà
  31. // ôóíêöèþ - îáðàáîò÷èê òèïà TCmdParser_f, êîòîðàÿ ïðèíèìàåò äâà ïàðàìåòðà - óêàçàòåëü íà ñòðîêó, è íà USB_DEVICE_INFO
  32. // childcount - êîëè÷åñòâî äî÷åðíèõ êîììàíä, íåîáõîäèìî óêàçàòü òî÷íîå êîëè÷åñòâî êîììàíä â ñåêöèè root äëÿ âûäåëåíèÿ ïîä íèõ
  33. // ïàìÿòè. Ïîñëå òîãî, êàê GPIB_InitializeCommand âåðíåò óêàçàòåëü íà ñòðóêòóðó sScpiCommand_t, åãî ìîæíî çàïîìíèòü â ïåðåìåííóþ è èñïîëüçîâàòü
  34. // êàê ñïèñîê êîììàíä ïðè ïåðåäà÷å â ôóíêöèþ parse(). Ïîñëå ñîçäàíèÿ root, äîáàâëÿåì âñå êîììàíäû, âûçûâàÿ
  35. // GPIB_AddChildCommand( sScpiCommand_t * OwnerCommand, char * header, char *shortheader, TCmdParser_f function, unsigned int childcount )
  36. // ãäå OwnerCommand - óêàçàòåëü íà êîììàíäó, äëÿ êîòîðîé äîáàâëÿåìàÿ êîììàíäà áóäåò äî÷åðíåé. Åñëè äîáàâëÿåìàÿ êîììàíäà íå äîëæíà áûòü
  37. // äî÷åðíåé, à äîëæíà áûòü îñíîâíîé (:SYSTem), íóæíî ïåðåäàòü óêàçàòåëü root. Îñòàëüíûå ïàðàìåòðû àíàëîãè÷íû GPIB_InitializeCommand
  38. // Êàæäûé âûçîâ GPIB_AddChildCommand âîçâðàùàåò óêàçàòåëü íà âíîâü ñîçäàííóþ êîììàíäó, êîòîðûé íóæíî ñîõðàíèòü â ïåðåìåííîé,
  39. // åñëè ñîçäàâàåìàÿ êîììàíäà áóäåò èìåòü äî÷åðíèå êîììàíäû.
  40. /*
  41. char * fGPIB_Parser_CMD1(char*); // -- ïðîòîòèïû
  42. char * fGPIB_Parser_CMD2(char*); //
  43. char * fGPIB_Parser_CMD3(char*); //
  44. char * fGPIB_Parser_CMD4(char*); //
  45. char * fGPIB_Parser_CMD5_1(char*); //
  46. //------------------------------------------------------------------------------------------------------------
  47. sScpiCommand_t Root; // -- ïåðåìåííàÿ õðàíèò êîììàíäó root
  48. sScpiCommand_t * root = GPIB_InitializeCommand( &Root, NULL, NULL, NULL, 5 ); // -- ïðåäïîëàãàåòñÿ ñîçäàòü 5 êîììàíä â root
  49. sScpiCommand_t * Command1 = GPIB_AddChildCommand( root, "CoMmanD1","CMD1", fGPIB_Parser_CMD1, 0 ); // -- êîììàíäà CMD1 íå áóäåò èìåòü äî÷åðíèõ. Îáðàáàòûâàòüñÿ êîììàíäà áóäåò ôóíêöèåé char * fGPIB_Parser_CMD1(char*)
  50. sScpiCommand_t * Command2 = GPIB_AddChildCommand( root, "CoMmanD2","CMD2", fGPIB_Parser_CMD2, 0 );
  51. sScpiCommand_t * Command3 = GPIB_AddChildCommand( root, "CoMmanD3","CMD3", fGPIB_Parser_CMD3, 0 );
  52. sScpiCommand_t * Command4 = GPIB_AddChildCommand( root, "CoMmanD4","CMD4", fGPIB_Parser_CMD4, 0 );
  53. sScpiCommand_t * Command5 = GPIB_AddChildCommand( root, "CoMmanD5","CMD5", fGPIB_Parser_CMD5, 1 ); // -- êîììàíäà áóäåò èìåòü äî÷åðíþþ
  54. sScpiCommand_t * Command5_1 = GPIB_AddChildCommand( Command5, "CoMmanD5_1","CM51", fGPIB_Parser_CMD5_1, 0 ); // -- êîììàíäà äîáàâëåíà ê êîììàíäå Command5 êàê äî÷åðíÿÿ
  55. */
  56. // Òàêèì îáðàçîì, äîáàâëÿòü è èçìåíÿòü êîëè÷åñòâî è ïîääåðæêó êîììàíä çíà÷èòåëüíî ïðîùå, ÷åì îáðàáàòûâàòü
  57. // âñþ ñòðîêó â ëîá ñ êó÷åé if-îâ
  58. // ==================== ïðîòîòèïû =========================================================
  59. // ============================= ÑÅÐÂÈÑÍÛÅ ÔÓÍÊÖÈÈ ===================================================
  60. // GPIB_InitializeCommand:
  61. // Initializes the GPIB command
  62. // @pointer - the pointer to the command entry to initialize
  63. // @header - the command header (name)
  64. // @shortheader - the short command name
  65. // @function - command handler
  66. // @childMax - the maximum amount of child commands
  67. // @enablerequest - boolean flag, allows the request mode for the command
  68. sScpiCommand_t * GPIB_InitializeCommand ( sScpiCommand_t * pCmd,
  69. const char * header,
  70. const char *shortheader,
  71. TCmdParser_f function,
  72. size_t childMax,
  73. BOOL enablerequest )
  74. {
  75. if( !IsCorrectPointer(pCmd) )
  76. return NULL;
  77. pCmd->enablerequest = enablerequest; // request mode enable
  78. pCmd->header = header; // full header
  79. pCmd->shortheader = shortheader; // short header
  80. pCmd->function = function; // handler
  81. pCmd->childcount = 0; // amount of child commands
  82. pCmd->childcountmax = childMax; // maximum available of child commands
  83. pCmd->pcommands = (sScpiCommand_t*)malloc( sizeof(sScpiCommand_t) * childMax ); // allocate memory for child commands
  84. pCmd->bTagArgUsed = FALSE;
  85. if( (NULL == pCmd->pcommands)
  86. && (childMax > 0) )
  87. {
  88. return NULL;
  89. }
  90. return pCmd;
  91. }
  92. //-----------------------------------------------------------------------------------------------------
  93. // GPIB_MakeSpecialCommand() transform the command to special command
  94. // Special command has an extra tag parameter to specialize the handler call.
  95. BOOL GPIB_MakeSpecialCommand ( sScpiCommand_t * pCmd, int xTag, BOOL bUsed )
  96. {
  97. if( !IsCorrectPointer(pCmd) )
  98. return FALSE;
  99. pCmd->bTagArgUsed = bUsed;
  100. pCmd->xTagArg = xTag;
  101. return TRUE;
  102. }
  103. // ------------------------------------------------------------------------------------------------------
  104. // GPIB_AddChildCommand:
  105. // Appends the child command to the specified owner @pOwnerCommand
  106. sScpiCommand_t * GPIB_AddChildCommand( sScpiCommand_t * pOwnerCommand, char * header, char * shortheader, TCmdParser_f function, size_t childMax, BOOL enablerequest )
  107. {
  108. if( !IsCorrectPointer(pOwnerCommand) )
  109. return NULL;
  110. sScpiCommand_t * ChildCommand;
  111. // check the limit of children
  112. if( pOwnerCommand->childcountmax > pOwnerCommand->childcount )
  113. {
  114. // Use already allocated memory for child command in @pOwnerCommand->pcommands block.
  115. ChildCommand = GPIB_InitializeCommand( &pOwnerCommand->pcommands[ pOwnerCommand->childcount ], header, shortheader, function, childMax, enablerequest );
  116. if( ChildCommand != NULL )
  117. pOwnerCommand->childcount++; // increment count of children
  118. }
  119. else
  120. ChildCommand = NULL; //error
  121. return ChildCommand;
  122. }
  123. //-------------------------------------------------------------------------------
  124. // GPIB_Parse:
  125. // Parse one command with parameters.
  126. // Note: the command must be without subsystem-character in the begining (semicolon)
  127. // E.g. SYSTem:TRIGger
  128. //
  129. sScpiCommand_t * GPIB_Parse( USB_DEVICE_INFO * udi, char * str, BOOL request, char * end )
  130. {
  131. sScpiCommand_t * searchRoot = udi->usbtmcGpib.gpib_search; // retrieve the root of the search
  132. // -----------------------------------------------------------------------------------------------------------
  133. // Validate the pointer @searchRoot
  134. if( ! IsCorrectPointer(searchRoot) )
  135. return NULL; // error
  136. // Validate the pointers @str and @end
  137. // It must be non NULL.
  138. if( NULL == str || NULL == end )
  139. return NULL;
  140. // Check if the @end greater than @str
  141. if( ChooseLowestPtrConst(str, end) == end )
  142. // error: the @str greater than @end
  143. // @end it's end of the string and must be greater.
  144. return NULL;
  145. // -----------------------------------------------------------------------------------------------------------
  146. // -----------------------------------------------------------------------------------------------------------
  147. // @sysNodeBegin: search for the subsystem delimiter (semicolon)
  148. char * sysNodeBegin = GPIB_StrChr_rw( str, GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN, end);
  149. // @sysNodeEnd: search for the end of all subsystems (whole command header, e.g. space btw cmd and data)
  150. //char * sysNodeEnd = strwhite( str ); // So, search for first white-charater
  151. char * sysNodeEnd = searchHeaderEnd( str, end ); // Search for the end of the header
  152. char charWhite = *sysNodeEnd; // Save the white character by offset @sysNodeEnd.
  153. // Calculate the string length
  154. size_t strLength = (int)((ptrdiff_t)(end) - (ptrdiff_t)(str));
  155. size_t strLength2 = strlen(str);
  156. // Choose the shortest one between strlen() and substraction btw @end and @str
  157. strLength = (strLength<strLength2 ? strLength : strLength2);
  158. BOOL bCommandFound = FALSE; // flag, is TRUE if a command found
  159. BOOL bRequest = FALSE; // is TRUE for the REQUEST command, e.g. *CMD? for "*CMD" command
  160. // Note: it is normal that @sysNodeBegin is NULL.
  161. // Note: it is normal that @sysNodeEnd is NULL.
  162. if( NULL != sysNodeBegin ) *sysNodeBegin = '\0'; // make the long command shorter - only one subsystem will be used til the semicolon
  163. if( NULL != sysNodeEnd ) *sysNodeEnd = '\0'; // make the long command shorter - replace white character with the null terminator
  164. // -----------------------------------------------------------------------------------------------------------
  165. // Validate the header
  166. if( TRUE != GPIB_CheckHeader(str, end) )
  167. //if( TRUE != GPIB_CheckHeader(str) )
  168. {
  169. // restore the subsystem delimiter
  170. if( sysNodeBegin != NULL ) *sysNodeBegin = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN;
  171. // restore the white character
  172. if( sysNodeEnd != NULL ) *sysNodeEnd = charWhite;
  173. /* ëèøíèé êîä - òà æå ñàìàÿ îøèáêà ãåíåðèðóåòñÿ â GPIB_CommandExecure, è îíà ïîëó÷àåòñÿ äóáëèðîâàíà
  174. // error: raise an error
  175. // 27/08/18 if( usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE, ERROR_USBTMC_EXECUTION, "'", 1 ) )
  176. // 30/08/18 if( usbtmc_RaiseError( udi, errClass_Command, ERROR_USBTMC_EXECUTION, "'", 1 ) )
  177. if( usbtmc_RaiseError( udi, errClass_Command, ERROR_USBTMC_INVALID_HEADER, "'", 1 ) )
  178. {
  179. //if( usbtmc_RaiseError_CatDescription( udi, str, strlen(str) ) ) // strlen(str): takes the command til the first '\0'
  180. if( usbtmc_RaiseError_CatDescription( udi, str, strLength ) )
  181. {
  182. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1) )
  183. {
  184. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  185. }
  186. }
  187. else
  188. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  189. }
  190. else
  191. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  192. */
  193. // return NULL
  194. return NULL;
  195. }
  196. if( GPIB_CHAR_MANDATORY_IEEE488_SIGN == str[0] && strLength < 3 )
  197. {
  198. }
  199. else
  200. {
  201. // search for the header in the command list from specified root (@searchRoot)
  202. for( size_t i = 0; i < searchRoot->childcount; ++i )
  203. {
  204. bCommandFound = FALSE;
  205. do
  206. {
  207. // -------------------------------------------------------------
  208. // Attempt 1.
  209. // -------------------------------------------------------------
  210. // Compare the command header
  211. if( GPIB_HeaderCompare( searchRoot->pcommands[i].header, str ) // the command header matchs
  212. || GPIB_HeaderCompare( searchRoot->pcommands[i].shortheader, str ) ) // the command short header matchs
  213. {
  214. bCommandFound = TRUE;
  215. // In case searchRoot->pcommands[i].enablerequest is FALSE, but
  216. // the command actually is a request, the header contain a request
  217. // character in the end. It is required to set @bRequst to appropriate value.
  218. if( GPIB_CHAR_REQUEST_SIGN == *(sysNodeEnd - 1) )
  219. bRequest = TRUE;
  220. break; // do-while
  221. }
  222. // -------------------------------------------------------------
  223. // Attempt 2.
  224. // -------------------------------------------------------------
  225. // Note: if @enablerequest it means the command in the list is registered
  226. // without question mark, e.g. ESE, but not ESE?. So it means the command
  227. // can be used as either "command" and "request". In this case GPIB_HeaderCompare
  228. // does not find full match
  229. // Check if the command is registered without the request mark (?).
  230. if( searchRoot->pcommands[i].enablerequest )
  231. {
  232. // get the header length
  233. // Note: @str string had been cut with null-terminator above.
  234. strLength = strlen( str );
  235. // Check if @str contain a request character
  236. if( (GPIB_CHAR_REQUEST_SIGN == str[ strLength-1 ])
  237. && (strLength > 1)
  238. )
  239. {
  240. // replace the request character with a null-terminator.
  241. str[ strLength-1 ] = '\0';
  242. // Perform another comparaion of the command header
  243. if( GPIB_HeaderCompare( searchRoot->pcommands[i].header, str ) // the command header matchs
  244. || GPIB_HeaderCompare( searchRoot->pcommands[i].shortheader, str ) ) // the command short header matchs
  245. {
  246. bCommandFound = TRUE;
  247. bRequest = TRUE;
  248. str[ strLength-1 ] = GPIB_CHAR_REQUEST_SIGN; // restore the request character
  249. break; // do-while
  250. }
  251. str[ strLength-1 ] = GPIB_CHAR_REQUEST_SIGN; // restore the request character
  252. }
  253. }
  254. }
  255. while(0);
  256. if( bCommandFound )
  257. {
  258. // Check is there next subsystem separator in the string.
  259. // If there no such separator, the the whole input command string is processed.
  260. if( sysNodeBegin != NULL )
  261. {
  262. // There are more subsystem separators
  263. *sysNodeBegin = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN; // restore subsystem separator
  264. if( sysNodeEnd != NULL ) *sysNodeEnd = charWhite; // restore white character
  265. udi->usbtmcGpib.gpib_owner = udi->usbtmcGpib.gpib_search; // save the command owner: searchRoot->pcommands[i]
  266. udi->usbtmcGpib.gpib_search = &searchRoot->pcommands[i]; // set the root for the searching in the next recursive call
  267. sysNodeBegin++; // skip subsystem separator
  268. return GPIB_Parse( udi, sysNodeBegin, bRequest, end ); // parse the command recursive in the found command
  269. }
  270. else // if the input string is processed til the end
  271. {
  272. if( sysNodeEnd != NULL ) // if there is a white character in the tail of header
  273. { // Note: a white character always presents.
  274. *sysNodeEnd = charWhite; // restore white character
  275. size_t nRespondBytes = 0; // @nRespondBytes - amount of sent bytes
  276. size_t nOffset = 0;
  277. // It is required to insert the delimiter between replies
  278. // relating to the different input requests in case more than one
  279. // command is in the string.
  280. if( bRequest )
  281. {
  282. /*
  283. // pointer to the buffer for respond
  284. BULKIN_HEADER * pBulkInHeader= (BULKIN_HEADER*) udi->EPBulkStatus.InPipe.pData;
  285. // if there are any bytes in the respond buffer - it must be a reply of another command
  286. if( 0 < pBulkInHeader->stRespondMessage.TransferSize )
  287. {
  288. // insert a delimiter
  289. udi->usbtmcGpib.pData[0] = GPIB_CHAR_RPLSEPARATOR_SIGN;
  290. udi->usbtmcGpib.pData++;
  291. nOffset++;
  292. }
  293. */
  294. if( udi->BulkRespondStatus.dwDeviceOut > 0 )
  295. {
  296. // insert a delimiter
  297. udi->usbtmcGpib.pData[0] = GPIB_CHAR_RPLSEPARATOR_SIGN;
  298. udi->usbtmcGpib.pData++;
  299. nOffset++;
  300. }
  301. }
  302. size_t paramLength = 0;
  303. // -------------
  304. // If the end of header reached - set @sysNodeEnd to NULL, and set @paramLength to 0
  305. sysNodeEnd++;
  306. if( sysNodeEnd >= end )
  307. sysNodeEnd = NULL;
  308. else
  309. paramLength = SubPointers( end, sysNodeEnd );
  310. // -------------
  311. // Enumerate parameters and pack it into the queue
  312. QUEUE QParameters;
  313. queue_create( SCPIBParam, MEMORY_SIZE_PARAMQUEUE, &QParameters ); // @SCPIBParam - global and static buffer
  314. // Check command tag:
  315. if(searchRoot->pcommands[i].bTagArgUsed == TRUE)
  316. {
  317. // push the tag-parameter into the queue
  318. queue_add( &QParameters,
  319. (char*)&searchRoot->pcommands[i].xTagArg,
  320. sizeof(searchRoot->pcommands[i].xTagArg) );
  321. }
  322. // Allow unlimited amount of non-request commands, and limited amount of requests
  323. if( !bRequest || udi->usbtmcGpib.cRequestCountSupport > 0 )
  324. {
  325. // request: decrease amount of allowed requests (@cRequestCountSupport)
  326. if( bRequest ) udi->usbtmcGpib.cRequestCountSupport--;
  327. int rcEnum = 1;
  328. if( NULL != sysNodeEnd && 0 != paramLength )
  329. {
  330. // Enumerate all the parameters and pack it into the queue @QParameters
  331. rcEnum = GPIB_EnumParameters( sysNodeEnd, paramLength, &QParameters, NULL );
  332. }
  333. if( rcEnum > 0 )
  334. {
  335. QParameters.nStringLen = paramLength;
  336. QParameters.pString = sysNodeEnd;
  337. // ----------------------------------------------------------------------------
  338. // It is required to keep command context to give
  339. // enough time the current command to send it's reply.
  340. // --- usbtmc_delete_function_context( udi ) ---
  341. // see USBTMC spec, rev 1.0, 2003, page 16, table 12, index 1
  342. // Stall and abort the endpoint in case the IRQ-transfer is in progress
  343. if(udi->BulkRespondStatus.INTransferInProgress == TRUE && bRequest)
  344. usbtmc_bulkin_stall_and_abort( udi );
  345. // call the command processor
  346. nRespondBytes += (searchRoot->pcommands[i].function( udi, &QParameters, bRequest ));
  347. udi->usbtmcGpib.pData += nRespondBytes; // shift the pointer of the reply buffer
  348. udi->BulkRespondStatus.RespondBufferSize -= (nRespondBytes + nOffset); // and decrease amount of free space.
  349. udi->BulkRespondStatus.dwDeviceOut += (nRespondBytes + nOffset); // Increase of output transfer.
  350. }
  351. else
  352. {
  353. // 27/08/18
  354. // GPIB_RaiseStandartError( udi, ERROR_GPIB_INVALID_ENUM_PARAMETERS, NULL, GPIB_ERROR_ID_EXE );
  355. GPIB_RaiseStandartError( udi, ERROR_GPIB_INVALID_ENUM_PARAMETERS, NULL, errClass_Autodetect );
  356. }
  357. }
  358. else
  359. {
  360. // 27/08/18
  361. // GPIB_RaiseStandartError( udi, ERROR_GPIB_TOO_MANY_REQUESTS, NULL, GPIB_ERROR_ID_EXE );
  362. GPIB_RaiseStandartError( udi, ERROR_GPIB_TOO_MANY_REQUESTS, NULL, errClass_Command );
  363. }
  364. return searchRoot;
  365. }
  366. break;
  367. }
  368. }
  369. }
  370. }
  371. // Reach this point in case the command header not found.
  372. if( bCommandFound == FALSE )
  373. {
  374. sScpiCommand_t * pseudo_result;
  375. sScpiCommand_t * SearchSave;
  376. sScpiCommand_t * OwnerSave;
  377. searchRoot = udi->usbtmcGpib.gpib_owner; // get the owner for the search
  378. // it is possible that optional header is omitted
  379. if( sysNodeBegin != NULL ) *sysNodeBegin = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN; // restore subsystem separator
  380. if( sysNodeEnd != NULL ) *sysNodeEnd = charWhite; // restore white character
  381. for( size_t i = 0; i < searchRoot->childcount; ++i )
  382. {
  383. if( IsOptionalHeader( searchRoot->pcommands[i].shortheader )
  384. || IsOptionalHeader( searchRoot->pcommands[i].header ) ) // optional header found
  385. {
  386. /*!*/SearchSave = udi->usbtmcGpib.gpib_search; // save the search pointer
  387. /*!*/OwnerSave = udi->usbtmcGpib.gpib_owner; // save the owner command
  388. udi->usbtmcGpib.gpib_owner = udi->usbtmcGpib.gpib_search;
  389. udi->usbtmcGpib.gpib_search = &searchRoot->pcommands[i]; // change the search point for a while
  390. pseudo_result = GPIB_Parse( udi, str, request, end); // call the parser recursively
  391. /*!*/udi->usbtmcGpib.gpib_search = SearchSave; // restore the search pointer
  392. /*!*/udi->usbtmcGpib.gpib_owner = OwnerSave; // restore the owner command
  393. if( pseudo_result != NULL )
  394. return pseudo_result; // command found among optional commands
  395. }
  396. }
  397. }
  398. return NULL;
  399. }
  400. /*
  401. //-------------------------------------------------------------------------------
  402. //
  403. // Parameters: str - óêàçàòåëü íà îäíó êîììàíäó. Ïðèìåð, "SYSTem:TRIGger"
  404. // Êîììàíäà ":SYSTem:TRIGger" íåêîððåêòíà, òàê êàê èìååòñÿ íåçíà÷àùåå äâîåòî÷èå â íà÷àëå.
  405. // Íóæíî óáèðàòü äâîåòî÷èå â íà÷àëå
  406. sScpiCommand_t * parse( USB_DEVICE_INFO * udi, char * str, BOOL request, char * end)
  407. {
  408. sScpiCommand_t * Search = udi->usbtmcGpib.gpib_search; // -- íîä äåðåâà, ñ êîòîðîãî íà÷èíàåòñÿ ïîèñê
  409. BULKIN_HEADER * pBulkInHeader= (BULKIN_HEADER*) udi->EPBulkStatus.InPipe.pData; // óêàçàòåëü íà íà÷àëî áóôåðà-îòâåòà, óêàçàòåëü íà çàãîëîâîê Bulk-IN
  410. // -----------------------------------------------------------------------------------------------------------
  411. if( !IsCorrectPointer(Search) ) return NULL; // -- ïðîâåðÿåì êîððåêòíîñòü óêàçàòåëÿ
  412. // -----------------------------------------------------------------------------------------------------------
  413. char * p = GPIB_StrChr_rw( str, GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN, end); // -- èùåì ñëåäóþùèé íîä â ñòðîêå
  414. char * s = strwhite( str ); // -- èùåì çàâåðøàþùèé ñèìâîë êîìàíäû
  415. char _s = *s; // -- ñîõðàíÿåì çàâåðøàþùèé ñèìâîë êîììàíäû
  416. int l; // -- õðàíèò äëèííó ñòðîêè
  417. BOOL bCommandFound = FALSE; // -- êîììàíäà íåíàéäåíà
  418. BOOL q = FALSE; // -- ðàâåí TRUE åñëè ïðèøåë çàïðîñ "*REQUEST?", Õîòÿ èìååòñÿ êîììàíäà "*REQUEST"
  419. if( p != NULL ) *p = 0; // -- åñëè íàøëè ñëåä. íîä, óêîðà÷èâàåì êîììàíäó, äåëàÿ èç ïîñëåäîâàòåëüíîñòè êîììàíä îäíó êîììàíäó
  420. if( s != NULL ) *s = 0; // -- åñëè íàøëè çàâåðøàþùèé ñèìâîë, çàìåíÿåì åãî íà íóëü òåðìèíàòîð
  421. // -----------------------------------------------------------------------------------------------------------
  422. if( GPIB_CheckHeader(str) != TRUE )
  423. {
  424. // ñíà÷àëà ãåíåðèì îøèáêó, strlen äîéäåò äî '\0'
  425. // à ïîòîì óæå âåðíåì ïðîáåë íà ìåñòî
  426. if( usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE, ERROR_USBTMC_EXECUTION, "'", 1 ))
  427. if(usbtmc_RaiseError_CatDescription( udi, str, strlen(str)))
  428. usbtmc_RaiseError_CatDescription( udi, "'", 1);
  429. if( p != NULL ) *p = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN; // -- âîññòàíàâëèâàåì äâîåòî÷èå
  430. if( s != NULL ) *s = _s; // -- âîññòàíàâëèâàåì white ñèìâîë, (åñëè ýòî íàïðèìåð ïðîáåë, îòäåëÿþùèé äàííûå)
  431. }
  432. else
  433. {
  434. if(!( *str == GPIB_CHAR_MANDATORY_IEEE488_SIGN && strlen(str)<=2 ))
  435. for(int i=0; i< Search->childcount; i++) // -- èùåì ïî òåêóùåìó íîäó ïîèñêà íóæíóþ êîììàíäó
  436. // ------ ïðîâåðÿåì ñîâïàäåíèÿ êîììàíä...
  437. // --------------------------------------
  438. if( TRUE==GPIB_HeaderCompare( Search->pcommands[i].header, str ) || // -- èëè åñëè ñîâïàëî èìÿ êîììàíäû
  439. TRUE==GPIB_HeaderCompare( Search->pcommands[i].shortheader, str ) || // -- èëè åñëè ñîâïàëà àááðåâèàòóðà êîììàíäû
  440. // ---------- ïðîâåðÿåì ñîâïàäåíèå çàïðîñà...............
  441. // -- ïðîâåðêà äàëüøå, åñëè èìÿ è àááðåâèàòóðà íå ñîâïàëè
  442. (Search->pcommands[i].enablerequest == TRUE && // -- èëè åñëè ðàçðåøåíî ñðàâíåíèå áåç '?'
  443. ( // ---------- ïðîâåðÿåì, åñòü ëè â êîíöå çàïðîñíûé ñèìâîë '?'
  444. ((l = strlen( str )) && (str[l-1] == '?')) && // ---- è '?' åñòü â êîíöå ñòðîêè
  445. ( // --------- ñèìâîë åñòü, ñðàâíèâàåì áåç ñèìâîëà
  446. 0==strncmp( Search->pcommands[i].header, str, l-1 ) || // -- ñâåðÿåì èìÿ áåç '?'
  447. 0==strncmp( Search->pcommands[i].shortheader, str, l-1 ) // -- ñâåðÿåì àááð áåç '?'
  448. ) && (l>1) && ((q = TRUE),q) // -- åñëè âñå óñëîâèÿ âûïîëíåíû, q=TRUE
  449. )
  450. )
  451. )
  452. {
  453. bCommandFound = TRUE;
  454. if (p != NULL ) // -- åñëè ñòðîêà ðàçîáðàíà íå ïîëíîñòüþ
  455. { if( p != NULL ) *p = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN; // -- âîññòàíàâëèâàåì äâîåòî÷èå
  456. if( s != NULL ) *s = _s; // -- âîññòàíàâëèâàåì white ñèìâîë, (åñëè ýòî íàïðèìåð ïðîáåë, îòäåëÿþùèé äàííûå)
  457. udi->usbtmcGpib.gpib_owner = udi->usbtmcGpib.gpib_search; // ñîõðàíÿåì âëàäåëüöà êîììàíäû Search->pcommands[i]
  458. udi->usbtmcGpib.gpib_search = &Search->pcommands[i];
  459. return parse( udi, p+1, q, end); // -- ðåêóðñèâíî ïàðñèì ñëåäóþùóþ êîììàíäó. ïîèñê â óæå íàéäåíîì íîäå
  460. }
  461. else // -- åñëè ñòðîêà ðàçîáðàíà ïîëíîñòüþ
  462. if( s != NULL ) // -- åñëè èìååòñÿ white ñèìâîë, à îí âñåãäà èìååòñÿ
  463. { *s = _s; // -- âîññòàíàâëèâàåì åãî
  464. int dwRespondBytes=0; // -- dwRespondBytes - êîëè÷åñòâî áàéò, îòïðàâëÿåìûõ â îòâåò íà êîììàíäó
  465. int dwOffset=0;
  466. if( q == FALSE && *(s-1) == '?' ) q = TRUE; // åñëè êîììàíäà äîáàâëåíà êàê RequestOnly, åå header ñîäåðæèò '?'. q=FALSE åñëè êîììàíäà RequestOnly. Ýòà ñòðîêà èñïðàâëÿåò ñèòóàöèþ
  467. // --------------------- âñòàâêà ðàçäåëèòåëÿ ; â îòâåòíîå ñîîáùåíèå ìåæäó îòâåòàìè ------------------------
  468. // --------------------------------------------------------------------------------------------------------
  469. if(q==TRUE // -- åñëè ïðèøåë ÇÀÏÐÎÑ
  470. &&
  471. pBulkInHeader->stRespondMessage.TransferSize // -- åñëè óæå áûëè äàííûå â áóôåðå îò ïðåäûäóùåé êîììàíäå
  472. &&
  473. (++dwOffset)) // -- óâåëè÷èâàåì Offset
  474. (udi->usbtmcGpib.pData++)[0] = ';'; // -- âñòàâëÿåì ðàçäåëèòåëü
  475. // --------------------------------------------------------------------------------------------------------
  476. if( end <= ++s ) s = NULL; // åñëè êîíåö ñòðîêè èëè êîíåö êîììàíäû (ðàçäåëèòåëü ñëåäîì) òî s=NULL
  477. unsigned int strl = SubPointers(end,s);
  478. // -------------------------- ýíóìåðóåì ïàðàìåòðû è ëîæèì èõ â î÷åðåäü --------
  479. QUEUE QParameters;
  480. queue_create( SCPIBParam, MEMORY_SIZE_PARAMQUEUE, &QParameters ); // áóôåð î÷åðåäè ãëîáàëüíûé è ñòàòè÷åñêèé.
  481. if(Search->pcommands[i].bTagArgUsed == TRUE)
  482. queue_add( &QParameters, (char*)&Search->pcommands[i].xTagArg, sizeof(Search->pcommands[i].xTagArg) );
  483. if( !q || (q && udi->usbtmcGpib.cRequestCountSupport-- > 0) )
  484. if( GPIB_EnumParameters( s, strl, &QParameters, NULL ) != -1 )
  485. {
  486. QParameters.strl = strl;
  487. QParameters.str = s;
  488. // ----------------------------------------------------------------------------
  489. //-- ïåðåä âûïîëíåíèåì GPIB ôóíêöèè íåëüçÿ óäàëÿòü êîíòåêñò,
  490. //-- âåäü ñëåä êîììàíäà ìîæåò åãî è íå èñïîëüçóåò,
  491. //-- à òåêóùàÿ íå óñïååò ïåðåäàòü äàííûå
  492. //usbtmc_delete_function_context( udi );
  493. // see USBTMC spec, rev 1.0, 2003, page 16, table 12, index 1
  494. if(udi->BulkRespondStatus.INTransferInProgress == TRUE && q)
  495. usbtmc_bulkin_stall_and_abort( udi );
  496. dwRespondBytes+= (Search->pcommands[i].function( udi, &QParameters, q )); // -- âûçûâàåì îáðàáîò÷èê êîììàíäû, ïåðåäàâàÿ åìó îñòàâøóþñÿ ÷àñòü ñòðîêè ïîñëå white ñèìâîëà
  497. udi->usbtmcGpib.pData+=dwRespondBytes; // -- ñäâèãàåì óêàçàòåëü áóôåðà, â êîòîðûé ñêëàäûâàþòñÿ îòâåòû
  498. udi->BulkRespondStatus.RespondBufferSize -= (dwRespondBytes+dwOffset); // -- óìåíüøàåì îáúåì äîñòóïíîãî ìåñòà â áóôåðå
  499. udi->BulkRespondStatus.dwDeviceOut+=(dwRespondBytes+dwOffset); // -- óâåëè÷èâàåì ðàçìåð îòâåòíîé ïåðåäà÷è
  500. } else GPIB_RaiseStandartError( udi, ERROR_GPIB_INVALID_ENUM_PARAMETERS, NULL, GPIB_ERROR_ID_EXE );
  501. else GPIB_RaiseStandartError( udi, ERROR_GPIB_TOO_MANY_REQUESTS, NULL, GPIB_ERROR_ID_EXE );
  502. return Search;
  503. }
  504. break;
  505. }
  506. // -- ñþäà ìû ïîïàäåì åñëè êîììàíäà íå íàéäåíà!
  507. if( bCommandFound == FALSE )
  508. {
  509. sScpiCommand_t * pseudo_result;
  510. sScpiCommand_t * SearchSave;
  511. sScpiCommand_t * OwnerSave;
  512. Search = udi->usbtmcGpib.gpib_owner; // ïîëó÷àåì õîçÿèíà
  513. // -- âîçìîæíî îïóùåí íåîáÿçàòåëüíûé çàãîëîâîê!
  514. if( p != NULL ) *p = GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN; // -- âîññòàíàâëèâàåì äâîåòî÷èå
  515. if( s != NULL ) *s = _s;
  516. for(int i=0; i< Search->childcount; i++)
  517. if( IsOptionalHeader(Search->pcommands[i].shortheader) || IsOptionalHeader(Search->pcommands[i].header)) // åñëè íàéäåíà îïöèîíàëüíàÿ êîììàíäà
  518. {
  519. // !!!!!!!!!!!!!
  520. SearchSave = udi->usbtmcGpib.gpib_search; // ñîõðàíÿåì òåêóùèé óêàçàòåëü íà òî÷êó ïîèñêà
  521. OwnerSave = udi->usbtmcGpib.gpib_owner; // ñîõðàíÿåì òåêóùèé óêàçàòåëü íà âëàäåëüöà êîììàíäû
  522. // !!!!!!!!!!!!!
  523. udi->usbtmcGpib.gpib_owner = udi->usbtmcGpib.gpib_search;
  524. udi->usbtmcGpib.gpib_search = &Search->pcommands[i]; // èçìåíÿåì íà âðåìÿ òåêóùèé óêàçàòåëü íà òî÷êó ïîèñêà
  525. pseudo_result = parse( udi, str, request, end);
  526. // !!!!!!!!!!!!!
  527. udi->usbtmcGpib.gpib_search = SearchSave; // âîññòàíàâëèâàåì ïðåæíèé óêàçàòåëü íà òî÷êó ïîèñêà
  528. udi->usbtmcGpib.gpib_owner = OwnerSave; // âîññòàíàâëèâàåì ïðåæíèé óêàçàòåëü íà âëàäåëüöà êîììàíäû
  529. // !!!!!!!!!!!!!
  530. if( pseudo_result != NULL ) return pseudo_result; // óðà, íàøëè êîììàíäó â äåðåâà â îäíîì èç îïöèîíàëüíûõ íîäîâ
  531. }
  532. }
  533. } // CheckHeader
  534. return NULL;
  535. }
  536. */
  537. //----------------------------------------------------------------------
  538. // GPIB_InitializeAllCommands:
  539. // Create a list of supported commands of the device.
  540. sScpiCommand_t * GPIB_InitializeAllCommands()
  541. {
  542. // Allocate memory for the root command
  543. sScpiCommand_t * root = (sScpiCommand_t *)malloc( sizeof(sScpiCommand_t) );
  544. if( !IsCorrectPointer(root) )
  545. return NULL;
  546. // -------------------------------------------------------------------------------------------------
  547. // Create a root command:
  548. root = GPIB_InitializeCommand( root, "root" , NULL, GPIB_DUMMY_FUNCTION, 16, FALSE );
  549. // -------------------------------------------------------------------------------------------------
  550. // Mandatory commands, add as a child of root command:
  551. GPIB_AddChildCommand( root, "*IDN?", "*IDN?", GPIB_Identification , 0, FALSE);
  552. GPIB_AddChildCommand( root, "*CLS" , "*CLS" , GPIB_Clear , 0, FALSE);
  553. GPIB_AddChildCommand( root, "*RST" , "*RST" , GPIB_Reset , 0, FALSE);
  554. GPIB_AddChildCommand( root, "*ESE" , "*ESE" , GPIB_EventStatusEnable , 0, TRUE );
  555. GPIB_AddChildCommand( root, "*ESR" , "*ESR" , GPIB_EventStatusRegister , 0, TRUE );
  556. GPIB_AddChildCommand( root, "*STB" , "*STB" , GPIB_StatusRegister , 0, TRUE );
  557. GPIB_AddChildCommand( root, "*SRE" , "*SRE" , GPIB_StatusEnableRegister, 0, TRUE );
  558. GPIB_AddChildCommand( root, "*TRG" , "*TRG" , GPIB_Trigger , 0, FALSE); // ?
  559. GPIB_AddChildCommand( root, "*WAI" , "*WAI" , GPIB_Wait , 0, FALSE); // ?
  560. GPIB_AddChildCommand( root, "*OPC" , "*OPC" , GPIB_OperationComplete , 0, TRUE );
  561. // -------------------------------------------------------------------------------------------------
  562. // Child commands of root:
  563. sScpiCommand_t * gpib_Mem =
  564. GPIB_AddChildCommand( root, "MEMORY", "MEM", GPIB_DEF_FUNCTION , 1, FALSE );
  565. // -------------------------------------------------------------------------------------------------
  566. // Child commands of "MEMORY":
  567. sScpiCommand_t * gpib_MemTable =
  568. GPIB_AddChildCommand( gpib_Mem, "TABLE", "TABL", GPIB_DEF_FUNCTION , 12, FALSE );
  569. // -------------------------------------------------------------------------------------------------
  570. // Create child commands for "MEMORY:TABLE":
  571. GPIB_AddChildCommand( gpib_MemTable, "POINTS", "POIN", GPIB_MemoryTablePoints , 0, TRUE );
  572. GPIB_AddChildCommand( gpib_MemTable, "DATE", "DATE", GPIB_MemoryTableDate , 0, TRUE );
  573. GPIB_AddChildCommand( gpib_MemTable, "TIME", "TIME", GPIB_MemoryTableTime , 0, TRUE );
  574. GPIB_AddChildCommand( gpib_MemTable, "TEMPERATURE", "TEMP", GPIB_MemoryTableTemp , 0, TRUE );
  575. GPIB_AddChildCommand( gpib_MemTable, "CONNECTOR", "CONN", GPIB_MemoryTableConnector, 0, TRUE );
  576. GPIB_AddChildCommand( gpib_MemTable, "ADAPTER", "ADAP", GPIB_MemoryTableAdapter , 0, TRUE );
  577. GPIB_AddChildCommand( gpib_MemTable, "ANALYZER", "ANAL", GPIB_MemoryTableAnalyzer , 0, TRUE );
  578. GPIB_AddChildCommand( gpib_MemTable, "OPERATOR", "OPER", GPIB_MemoryTableOperator , 0, TRUE );
  579. GPIB_AddChildCommand( gpib_MemTable, "PLACE", "PLAC", GPIB_MemoryTablePlace , 0, TRUE );
  580. GPIB_AddChildCommand( gpib_MemTable, "DATA", "DATA", GPIB_MemoryTableData , 0, TRUE );
  581. // ---------------------------------------------------------------------------------------------------------------
  582. // Child commands of "MEMORY:TABLE":
  583. sScpiCommand_t * gpib_MemTableTher =
  584. GPIB_AddChildCommand( gpib_MemTable, "THERMO", "THER", GPIB_DEF_FUNCTION , 1, FALSE );
  585. sScpiCommand_t * gpib_MemTableTherCorr =
  586. GPIB_AddChildCommand( gpib_MemTableTher, "CORRECTION", "CORR", GPIB_DEF_FUNCTION , 4, FALSE );
  587. // ---------------------------------------------------------------------------------------------------------------
  588. // Child commands of "MEMORY:TABLE:THERMO:CORRECTION":
  589. //GPIB_MakeSpecialCommand(
  590. GPIB_AddChildCommand( gpib_MemTableTherCorr,"MAGNITUDE", "MAGN", GPIB_MemTableTherCorrMagniture, 0, TRUE );
  591. GPIB_AddChildCommand( gpib_MemTableTherCorr,"PHASE" , "PHAS", GPIB_MemTableTherCorrPhase, 0, TRUE );
  592. GPIB_AddChildCommand( gpib_MemTableTherCorr,"POINTS" , "POIN", GPIB_MemTableTherCorrPoints, 0, TRUE );
  593. sScpiCommand_t * gpib_MemTableTherCorrFreq =
  594. GPIB_AddChildCommand( gpib_MemTableTherCorr,"FREQUENCY", "FREQ", GPIB_DEF_FUNCTION, 2, FALSE );
  595. // ---------------------------------------------------------------------------------------------------------------
  596. // Child commands of "MEMORY:TABLE:THERMOCOMPENSATION:FREQUENCY":
  597. GPIB_AddChildCommand( gpib_MemTableTherCorrFreq, "START", "STAR", GPIB_MemTableTherCorrFreqStart, 0, TRUE );
  598. GPIB_AddChildCommand( gpib_MemTableTherCorrFreq, "STOP" , "STOP", GPIB_MemTableTherCorrFreqStop, 0, TRUE );
  599. // ---------------------------------------------------------------------------------------------------------------
  600. // Child commands of "MEMORY:TABLE":
  601. sScpiCommand_t * gpib_MemTableFreq =
  602. GPIB_AddChildCommand( gpib_MemTable, "FREQUENCY", "FREQ", GPIB_DEF_FUNCTION, 5, FALSE );
  603. // ---------------------------------------------------------------------------------------------------------------
  604. // Child commands of "MEMORY:TABLE:FREQUENCY":
  605. // MEMORY:TABLE:FREQUENCY:START?
  606. GPIB_AddChildCommand( gpib_MemTableFreq, "START", "STAR", GPIB_MemoryTableFreqStart, 0, TRUE ),
  607. // MEMORY:TABLE:FREQUENCY:STOP?
  608. GPIB_AddChildCommand( gpib_MemTableFreq, "STOP", "STOP" , GPIB_MemoryTableFreqStop, 0, TRUE ),
  609. // MEMORY:TABLE:FREQUENCY:TYPE?
  610. GPIB_AddChildCommand( gpib_MemTableFreq, "TYPE", "TYPE", GPIB_MemoryTableFreqType, 0, TRUE );
  611. sScpiCommand_t * gpib_MemTableFreqSegm =
  612. // MEMORY:TABLE:FREQUENCY:SEGM
  613. GPIB_AddChildCommand( gpib_MemTableFreq, "SEGM", "SEGM", GPIB_DEF_FUNCTION, 1, FALSE );
  614. // MEMORY:TABLE:FREQUENCY:SEGM:DATA?
  615. GPIB_AddChildCommand( gpib_MemTableFreqSegm,"DATA", "DATA", GPIB_MemoryTableFreqSegmData,0,TRUE );
  616. // MEMORY:TABLE:FREQUENCY:DATA?
  617. GPIB_AddChildCommand( gpib_MemTableFreq, "DATA", "DATA", GPIB_MemoryTableFreqData, 0, TRUE );
  618. // ---------------------------------------------------------------------------------------------------------------
  619. // Child commands of root:
  620. sScpiCommand_t * gpib_DeviceDependent =
  621. GPIB_AddChildCommand( root, "MEASURE", "MEAS", GPIB_DEF_FUNCTION, 1, FALSE); //root function 8
  622. // ---------------------------------------------------------------------------------------------------------------
  623. // Child commands of "MEASURE":
  624. GPIB_AddChildCommand( gpib_DeviceDependent, "TEMPERATURE", "TEMP", GPIB_GetTemperature, 0, TRUE); //C÷èòûâàåò òåìïåðàòóðó âíóòðè êàëèáðîâî÷íîãî ìîäóëÿ (òîëüêî çàïðîñ).
  625. // ---------------------------------------------------------------------------------------------------------------
  626. // Child commands of root:
  627. sScpiCommand_t * gpib_Interface =
  628. GPIB_AddChildCommand( root, "INTERFACE", "INT", GPIB_DEF_FUNCTION, 1, FALSE ); //root function 7
  629. // ---------------------------------------------------------------------------------------------------------------
  630. // Child commands of "INTERFACE":
  631. GPIB_AddChildCommand( gpib_Interface, "SWITCH", "SW", GPIB_InterfaceSwitch, 0, TRUE );
  632. // ---------------------------------------------------------------------------------------------------------------
  633. // Child commands of root:
  634. sScpiCommand_t * gpib_System =
  635. GPIB_AddChildCommand( root, "[SYSTEM]", "[SYST]", GPIB_DEF_FUNCTION, 3, FALSE ); //root function 4
  636. // ---------------------------------------------------------------------------------------------------------------
  637. // Child commands of "SYSTEM":
  638. GPIB_AddChildCommand( gpib_System, "VERSION?", "VERS?", GPIB_SystemVersion, 0, FALSE );
  639. sScpiCommand_t * gpib_SystemErr =
  640. GPIB_AddChildCommand( gpib_System, "ERROR", "ERR", GPIB_SystemError, 2, TRUE );
  641. sScpiCommand_t * gpib_Source =
  642. GPIB_AddChildCommand( gpib_System, "[SWITCH]", "[SWIT]", GPIB_DEF_FUNCTION, 3, FALSE ); //root function 9
  643. // ---------------------------------------------------------------------------------------------------------------
  644. // Child commands of "SYSTEM:ERR":
  645. GPIB_AddChildCommand( gpib_SystemErr, "NEXT?", "NEXT?", GPIB_SystemError, 0, FALSE);
  646. GPIB_AddChildCommand( gpib_SystemErr, "ALL?", "ALL?", GPIB_SystemErrorAll, 0, FALSE);
  647. // ---------------------------------------------------------------------------------------------------------------
  648. // Child commands of "SYSTEM:SWITCH"
  649. GPIB_AddChildCommand( gpib_Source, "COUNT", "COUN", GPIB_SwitchCount, 0, TRUE );
  650. GPIB_AddChildCommand( gpib_Source, "STATE", "STAT", GPIB_SwitchState, 0, TRUE );
  651. GPIB_AddChildCommand( gpib_Source, "LIST", "LIST", GPIB_SwitchList, 0, TRUE );
  652. // ---------------------------------------------------------------------------------------------------------------
  653. // Child commands of root:
  654. // sScpiCommand_t * gpib_Status =
  655. // GPIB_AddChildCommand( root, "STATUS", "STAT", GPIB_DEF_FUNCTION, 3, FALSE ); //root function 5
  656. // ---------------------------------------------------------------------------------------------------------------
  657. // Child commands of "STATUS":
  658. // GPIB_AddChildCommand( gpib_Status, "PRESET", "PRES", GPIB_StatusPreset, 0, FALSE ); // No Subcomands
  659. // sScpiCommand_t * gpib_StatusOperation =
  660. // GPIB_AddChildCommand( gpib_Status, "OPERATION", "OPER", GPIB_StatusOperationEvent, 3, TRUE ); // 3 Subcommands, Request Enable -> EVENt?
  661. // sScpiCommand_t * gpib_StatusQuestionable =
  662. // GPIB_AddChildCommand( gpib_Status, "QUESTIONABLE","QUES", GPIB_StatusQuestionableEvent, 3, TRUE ); // 3 Subcommands, Request Enable -> EVENt?
  663. // ---------------------------------------------------------------------------------------------------------------
  664. // Child commands of "STATUS:OPERATION":
  665. // GPIB_AddChildCommand( gpib_StatusOperation, "EVENT?", "ENENt?", GPIB_StatusOperationEvent, 0, FALSE ); // No Subcomands, Request Only
  666. // GPIB_AddChildCommand( gpib_StatusOperation, "CONDition?", "COND?", GPIB_StatusOperationCondition, 0, FALSE ); // No Subcomands, Request Only
  667. // GPIB_AddChildCommand( gpib_StatusOperation, "ENABLE", "ENAB", GPIB_StatusOperationEnable, 0, TRUE ); // No Subcomands, Request enable
  668. // ---------------------------------------------------------------------------------------------------------------
  669. // Child commands of "STATUS:QUESTIONABLE":
  670. // GPIB_AddChildCommand( gpib_StatusQuestionable, "EVENT?", "ENENt?", GPIB_StatusQuestionableEvent, 0, FALSE ); // No Subcomands, Request Only
  671. // GPIB_AddChildCommand( gpib_StatusQuestionable, "CONDition?","COND?", GPIB_StatusQuestionableCondition, 0, FALSE ); // No Subcomands, Request Only
  672. // GPIB_AddChildCommand( gpib_StatusQuestionable, "ENABLE", "ENAB", GPIB_StatusQuestionableEnable, 0, TRUE ); // No Subcomands, request enable
  673. // ---------------------------------------------------------------------------------------------------------------
  674. return root;
  675. }
  676. // GPIB_TrimCommand:
  677. // Removes either the leading and trailing white characters from the command string
  678. // Returns the length of command
  679. int GPIB_TrimCommand( char * begin, char * end, char * * pCmdStart, char * * pCmdEnd )
  680. {
  681. // check the input pointers
  682. if( NULL == end || NULL == begin || NULL == pCmdStart || NULL == pCmdEnd )
  683. return -1;
  684. if( SubPointers(end, begin) <= 0 )
  685. return -1;
  686. // Skip leading white characters
  687. while( IsWhiteOrEndChar( *begin ) )
  688. {
  689. begin++;
  690. }
  691. // Skip trailing white characters
  692. do
  693. {
  694. end--;
  695. }
  696. while( IsWhiteOrEndChar( *end ) );
  697. end++;
  698. *pCmdEnd = end;
  699. *pCmdStart = begin;
  700. return SubPointers( end, begin );
  701. }
  702. // GPIB_SearchCommand:
  703. // Searches for the end of command in the string @begin til the @end.
  704. // @ppCmdEnd - the pointer to the receiving cell of pointer to the end of command
  705. // Note: the function processes GPIB strings and GPIB datablocks.
  706. int GPIB_SearchCommand( const char * begin, const char * end, const char * * ppCmdEnd )
  707. {
  708. // check the input pointers
  709. if( NULL == end || NULL == begin )
  710. return -1;
  711. // check the input pointers
  712. if( SubPointers(end, begin) <= 0 )
  713. return -1;
  714. const char * iter = begin;
  715. const char * near;
  716. do
  717. {
  718. // Search for special characters in the string since @iter til the @end
  719. const char * separator = GPIB_StrChr( iter, GPIB_CHAR_CMDSEPARATOR_SIGN, end ); // search for the command separator
  720. const char * datablock = GPIB_StrChr( iter, GPIB_CHAR_DATATABLE_SIGN, end ); // search for the datablock
  721. const char * squote = GPIB_StrChr( iter, GPIB_CHAR_SINGLEQUOTE_SIGN, end ); // search for the quoted string
  722. const char * dquote = GPIB_StrChr( iter, GPIB_CHAR_DOUBLEQUOTE_SIGN, end ); // search for the quoted string
  723. // Select the first faced special character in the string since @iter til the @end
  724. near = ChooseLowestPtrConst( squote, dquote );
  725. near = ChooseLowestPtrConst( near, separator );
  726. near = ChooseLowestPtrConst( near, datablock );
  727. // check the simplest case: no separator characters found (and any other special characters)
  728. if( NULL == near )
  729. {
  730. // the whole string [@begin ... @end] is a command
  731. if( NULL != ppCmdEnd ) *ppCmdEnd = end;
  732. // return the length of command
  733. return SubPointers( end, begin );
  734. }
  735. // check if the first command does contain neither datablock or quotes
  736. // In this case a separator is faced first
  737. if( separator == near )
  738. {
  739. // the string [@iter ... @separator] is a command
  740. if( NULL != ppCmdEnd ) // fixed: 23/08/18
  741. {
  742. *ppCmdEnd = separator;
  743. }
  744. // return the length of command
  745. return SubPointers( separator, iter );
  746. }
  747. // check if the double quote is faced first
  748. if( dquote == near )
  749. {
  750. // the string contains GPIB string. It is required to skip it.
  751. // search a closing quote
  752. dquote = GPIB_StrChr( iter, GPIB_CHAR_DOUBLEQUOTE_SIGN, end );
  753. if( NULL == dquote )
  754. {
  755. // error: unpaired quote found
  756. return -1;
  757. }
  758. // skip the quoted string
  759. iter = (dquote + 1);
  760. continue;
  761. }
  762. // check if the single quote is faced first
  763. if( squote == near )
  764. {
  765. // the string contains GPIB string. It is required to skip it.
  766. // search a closing quote
  767. squote = GPIB_StrChr( iter, GPIB_CHAR_SINGLEQUOTE_SIGN, end );
  768. if( NULL == squote )
  769. {
  770. // error: unpaired quote found
  771. return -1;
  772. }
  773. // skip the quoted string
  774. iter = (squote + 1);
  775. continue;
  776. }
  777. // check if the datablock is faced first
  778. if( datablock == near )
  779. {
  780. size_t nDataBlock;
  781. // check if it is valid datablock
  782. if( IsDataBlock( datablock, SubPointers(end, datablock), &nDataBlock, NULL ) )
  783. {
  784. // datablock is valid
  785. // skip datablock
  786. iter = (datablock + nDataBlock);
  787. }
  788. else
  789. {
  790. // datablock is invalid
  791. // skip the datablock signature
  792. // maybe, it is not datablock.
  793. iter = (datablock + 1);
  794. }
  795. continue;
  796. }
  797. }
  798. // continue until the end of string (@end is reached)
  799. // and interrupt in case @near is null.
  800. while( (NULL != near) && SubPointers(end, iter) > 0 );
  801. // no separator found
  802. if( NULL != ppCmdEnd ) *ppCmdEnd = end;
  803. // the whole string is a command
  804. // return the length of command
  805. return SubPointers( end, begin );
  806. }
  807. // -----------------------------------
  808. // GPIB_CommandExecute() âûïîëíåíèå ñòðîêè êîììàíä GPIB.
  809. // root - óêàçàòåëü íà root êîììàíäó äåðåâà êîììàíä
  810. // GPIB_Commands_String - óêàçàòåëü íà ñòîêó êîììàíä GPIB, ðàçäåëåííûõ òî÷êîé ñ çàïÿòîé
  811. int GPIB_CommandExecute( USB_DEVICE_INFO * udi, const char * input_str )
  812. {
  813. size_t length = udi->BulkMessageStatus.OutTransferSize; // get the input string length
  814. char * iter = GPIB_StrCopyToCache( input_str, length ); // bufferize the string into internal cache
  815. // now @iter points to the cached string
  816. if( NULL == iter ) // Check if the string is cached successfully
  817. return -1; // error: cache overflow
  818. char * end = iter + length; // end of input string
  819. // Check the end of string: check the last character
  820. if( GPIB_CHAR_ENDLINE_SIGN == *(end-1) )
  821. {
  822. // Shift @end back for one character
  823. // Now: @end points to end-of-line character
  824. end --;
  825. }
  826. else
  827. {
  828. // error: end-of-line character not found.
  829. // Maybe, input string is too long.
  830. return -1;
  831. }
  832. //--------------------------------------------------------------------------
  833. sScpiCommand_t * xResult; // pointer to the processed command
  834. sScpiCommand_t * pCmdRoot = udi->usbtmcGpib.gpib_root; // root-command
  835. sScpiCommand_t * pCmdSearch = pCmdRoot; // search pointer in the tree
  836. //--------------------------------------------------------------------------
  837. udi->usbtmcGpib.cRequestCountSupport = 1;
  838. //--------------------------------------------------------------------------
  839. udi->usbtmcGpib.gpib_owner = pCmdRoot; // search in ROOT by default
  840. //--------------------------------------------------------------------------
  841. size_t nCmdProcessed = 0; // count of processed commands
  842. int nCmdLength = 0;
  843. do
  844. {
  845. // Skip the only first command separator
  846. if( GPIB_CHAR_CMDSEPARATOR_SIGN == *iter )
  847. {
  848. iter++;
  849. }
  850. // Search for the end of the command
  851. nCmdLength = GPIB_SearchCommand( iter, end, NULL );
  852. if( nCmdLength > 0 )
  853. {
  854. char * cmdStart;
  855. char * cmdEnd;
  856. // Trim the command
  857. if( GPIB_TrimCommand( iter, (iter + nCmdLength), &cmdStart, &cmdEnd ) > 0 )
  858. {
  859. if( GPIB_CHAR_MANDATORY_IEEE488_SIGN == *cmdStart )
  860. {
  861. pCmdSearch = pCmdRoot; // change the search pointer to the root
  862. }
  863. else
  864. if( GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN == *cmdStart )
  865. {
  866. pCmdSearch = pCmdRoot; // change the search pointer to the root
  867. cmdStart++; // skip subsystem separator
  868. }
  869. udi->usbtmcGpib.gpib_search = pCmdSearch;
  870. udi->usbtmcGpib.sgpib_current = cmdStart;
  871. xResult = GPIB_Parse( udi, cmdStart, FALSE, cmdEnd );
  872. if( NULL != xResult )
  873. {
  874. // Success
  875. nCmdProcessed++; // increment the processed command counter
  876. }
  877. else
  878. {
  879. // Error
  880. // Form a error message
  881. /* 27/08/18 if(usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE, ERROR_USBTMC_INVALID_HEADER, "'", 1)) */
  882. if(usbtmc_RaiseError( udi, errClass_Command, ERROR_USBTMC_INVALID_HEADER, "'", 1))
  883. {
  884. if(usbtmc_RaiseError_CatDescription( udi, cmdStart, SubPointers(cmdEnd, cmdStart) ) )
  885. {
  886. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1 ) )
  887. {
  888. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  889. }
  890. }
  891. else
  892. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  893. }
  894. else
  895. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  896. xResult = pCmdSearch;
  897. }
  898. pCmdSearch = xResult; // set the search point for the next command
  899. iter += nCmdLength;
  900. }
  901. else break;
  902. }
  903. }
  904. while( nCmdLength > 0 );
  905. return nCmdProcessed;
  906. }
  907. //
  908. //// -----------------------------------
  909. //// GPIB_CommandExecute() âûïîëíåíèå ñòðîêè êîììàíä GPIB.
  910. //// root - óêàçàòåëü íà root êîììàíäó äåðåâà êîììàíä
  911. //// GPIB_Commands_String - óêàçàòåëü íà ñòîêó êîììàíä GPIB, ðàçäåëåííûõ òî÷êîé ñ çàïÿòîé
  912. //int GPIB_CommandExecute( USB_DEVICE_INFO * udi, char * str ) {
  913. // // ----------------------------------------------------------------------------------------------------------
  914. //
  915. // sScpiCommand_t * rc; // -- óêàçàòåëü íà âûïîëíåííóþ êîììàíäó
  916. // sScpiCommand_t * root = udi->usbtmcGpib.gpib_root; // -- êîðíåâàÿ êîììàíäà äðåâà êîììàíä
  917. // sScpiCommand_t * Search=root; // -- óêàçàòåëü íà òåêóùèé "ïóòü" ïîèñêà êîììàíäû
  918. ////-----------------------------------------------------
  919. // unsigned int datatablesize = 0; // -- ðàçìåð òàáëèöû äàííûõ
  920. // unsigned int strl; // -- ðàçìåð âõ ñòðîêè
  921. // unsigned int ret_val = 0; // -- âîçâðàùàåìîå çíà÷åíèå êîëè÷åñòâà ðàñïîçíàííûõ êîììàíä
  922. ////-----------------------------------------------------
  923. // BOOL datatable_found; // -- òàáëèöà äàííûõ íàéäåíà â ñòðîêå
  924. ////-----------------------------------------------------
  925. // char * semicolon=NULL; // -- óêàçàòåëü íà ðàçäåëèòåëü êîììàíä, åñëè òàêîé åñòü â ñòðîêå
  926. // char * datatable; // -- óêàçàòåëü íà òàáëèöó äàííûõ
  927. // char * stre; // -- êîíåö ñòðîêè
  928. // char * cmde; // êîíåö êîììàíäû,
  929. // char * gstre; // -- êîíåö ñòðîêè GPIB ("")
  930. // char * squote; // -- êàâû÷êè ñòðîêè GPIB
  931. // char * dquote; // -- êàâû÷êè ñòðîêè GPIB
  932. // char * quote; // -- êàâû÷êè ñòðîêè GPIB
  933. ////-----------------------------------------------------
  934. //
  935. // // -------------------------------
  936. // udi->usbtmcGpib.gpib_owner = root; // -- ïîèñê â root
  937. // // -------------------------------
  938. // udi->usbtmcGpib.cRequestCountSupport = 1; // -- òîëüêî îäèí çàïðîñ â ñòðîêå
  939. // // -------------------------------------------
  940. // strl = udi->BulkMessageStatus.OutTransferSize; // -- äëèííà ïåðåäàííîé ñòðîêè êîììàíä
  941. // str = GPIB_StrCopyToCache( str, strl ); // -- äîáàâëÿåò íóëü ñèìâîë ê êîíöó ñòðîêè
  942. // stre = str + strl - 1; // -- êîíåö ñòðîêè. äî 0x0A
  943. // if(str == NULL) return -1; // -- ÎØÈÁÊÀ ! ÍÅÒ ÏÀÌßÒÈ!
  944. // // -------------------------------------------
  945. //
  946. //
  947. // // ------- ÈÍÈÖÈÀËÈÇÀÖÈß ÏÅÐÅÄÀ×È ------
  948. // // ïðîèçâåäåíà â DEV_DEP_MSG_OUT()
  949. // // -------------------------------------
  950. //
  951. // strucase( str, strl); // -- ïåðåâîäèì ñòðîêó â ÂÅÐÕÍÈÉ ÐÅÃÈÑÒÐ
  952. //
  953. // while( *str || semicolon != NULL) // -- ïîêà íå äîøëè äî êîíöà ñòðîêè
  954. // {
  955. // gstre = str;
  956. //
  957. // // ----------------------------------------------------------------------------------------
  958. // // -- ïðîïóñê ñòðîêè GPIB
  959. // do
  960. // {
  961. //
  962. // datatable = GPIB_StrChr_rw( gstre, GPIB_CHAR_DATATABLE_SIGN, stre ); // +ïîèñê ñèãíàòóðû òàáëèöû äàííûõ
  963. // semicolon = GPIB_StrChr_rw( gstre, GPIB_CHAR_CMDSEPARATOR_SIGN, stre ); // +ïîèñê ðàçäåëèòåëÿ êîììàä
  964. // squote = GPIB_StrChr_rw( gstre, GPIB_CHAR_SINGLEQUOTE_SIGN, stre ); // +ïîèñê ñòðîêè GPIB
  965. // dquote = GPIB_StrChr_rw( gstre, GPIB_CHAR_DOUBLEQUOTE_SIGN, stre ); // +ïîèñê ñòðîêè GPIB
  966. //
  967. // if(quote = ChooseLowestPtr(squote,dquote)) // -- âîçâðàùàåò íàèáëèæàéøèé óêàçàòåëü (íàèìåíüøèé, åñëè îáà íå NULL. Åñëè îäèí NULL, âîçâðàùàåò âòîðîé)
  968. // if( quote == ChooseLowestPtr( quote, semicolon ) ) // -- åñëè íà ïóòè ñòðîêà GPIB (êîòîðàÿ ìîæåò ñîäåðæàòü ';')
  969. // gstre = GPIB_GetStringEnd_rw( quote, strl - SubPointers(quote, str) ); // -- èùåì åå êîíåö
  970. // else
  971. // gstre = NULL;
  972. // else
  973. // gstre = NULL;
  974. //
  975. // }
  976. // while( gstre != NULL );
  977. // // ----------------------------------------------------------------------------------------
  978. //
  979. // // íóæíî ðàçäåëèòü ñòðîêó íà êîììàíäû, (ðàçäåëèòåëü ;) ïðè÷åì, ó÷åñòü, ÷òî
  980. // // ïîñëå êàæäîé êîììàíäû ìîãóò áûòü äàííûå è ÒÀÁËÈÖÛ äàííûõ òèïà #NZZZ..ZBBBBBB...B (ñì GPIB)
  981. // // èëè GPIB ñòðîêè, çàêëþ÷åííûå â êàâû÷êè ("") èëè (' ').
  982. // // Äëÿ ýòîãî íóæíî ïðîïàðñèòü òàáëèöû, òàê êàê îíè ìîãóò ñîäåðæàòü ðàçäåëèòåëü (;)
  983. // // à òàêæå ñòðîêè GPIB, îíè òîæå ìîãóò ñîäåðæàòü âñå ÷òî óãîäíî
  984. //
  985. // // =================================================================================================================
  986. //
  987. //
  988. // // ---------- ïðîïóñê òàáëèö äàííûõ -----------------------------
  989. //
  990. // datatable_found = FALSE;
  991. // if(datatable!=NULL && (semicolon==NULL || ((unsigned int)semicolon> (unsigned int)datatable))) // åñëè ñèãíàòóðà îáíàðóæåíà è îíà ðàíüøå ðàçäåëèòåëÿ
  992. // {
  993. // if(IsNUMBER(*(datatable+1))) // -- åñëè çà # ñëåäóåò öèôðà N ( öèôðà îïðåäåëÿåò äëèííó ÷èñëà ñëåäîì çà íåé )
  994. // {
  995. // datatable_found = TRUE; // -- òàáëèöà äàííûõ îáíàðóæåíà
  996. // // -- åñëè çà # è öèôðîéN ñëåäóåò N öèôð, òî ýòî çàãîëîâîê òàáëèöû äàííûõ
  997. // for( int m=1 ; datatable_found && (m<=(HexCharToNumber(*(datatable+1)))) ; m++)
  998. // if( !IsNUMBER( *(datatable+1+m) ) ) // -- ïðîâåðÿåì ÷òî âñå ýòî öèôðû
  999. // datatable_found = FALSE; // -- âûõîä èç öèêëà (ñì çàãîëîâîê for)
  1000. // }
  1001. // }
  1002. // else
  1003. // datatable_found = FALSE; // -- òàáëèà äàííûõ íå îáíàðóæåíà
  1004. // // -------------------------------------------------------------
  1005. //
  1006. //
  1007. // if(datatable_found==FALSE) // -- åñëè íå îáíàðóæåíà òàáëèöà èëè ðàçäåëèòåëü ðàíüøå òàáëèöû
  1008. // {
  1009. // if(semicolon!=NULL)
  1010. // {
  1011. // *semicolon = 0x00; // -- äåëèì êîììàíäó
  1012. // cmde = semicolon;
  1013. // }
  1014. // else
  1015. // cmde = stre; // -- êîíåö ñîîáùåíèÿ
  1016. // }
  1017. // else
  1018. // {
  1019. // semicolon = NULL;
  1020. // char * data;
  1021. // datatablesize = 0;
  1022. // datatable++; // -- ïðîïóñêàåì # //str++; //!#! #!#
  1023. //
  1024. //
  1025. // int n = HexCharToNumber(*(datatable)); // +öèôðà N îïðåäåëÿåò êîëè÷åñòâî öèôð ïîñëå #NZZZZZBBBBBBBBBBB
  1026. // // +N - êîëè÷åñòâî Z
  1027. // // +Z - öèôðû ñîñòàâëÿþò ÷èñëî, êîòîðîå îïðåäåëÿåò äëèííó òàáëèöû ( êîëè÷åòñâî B )
  1028. // data = datatable + n + 1; // +óñòàíàâëèâàåì óêàçàòåëü íà íà÷àëî òàáëèöû
  1029. // datatable++; // +óñò óêàçàòåëü íà íà÷àëî ÷èñëà ZZZZ
  1030. // StrToInt( datatable, n, &n ); // +êîíâåðòèóåì ÷èñëî çàïèñàííîå â ZZZZ â str â ÷èñëî â int â n
  1031. //
  1032. // // --- òàáëèöà äàííûõ íà÷èíàåòñÿ ñ datatable è äëèííà åå n
  1033. //
  1034. // datatable += n+1; // +ïðûãàåì ê êîíöó òàáëèöû äàííûõ !#!
  1035. // cmde = datatable;
  1036. // semicolon = GPIB_StrChr_rw( datatable, GPIB_CHAR_CMDSEPARATOR_SIGN, stre); // +èùåì ðàçäåëèòåëü ñíîâà, íî óæå ïîñëå òàáëèöû äàííûõ
  1037. // if(semicolon == datatable) datatable++; // +åñëè îí ñðàçó ïîñëå òàáëèöû, ïðîñïóñêàåì åãî, ÷òîáû íå âûïîëíÿòü ïóñòóþ êîììàíäó
  1038. //
  1039. // datatable = data;
  1040. // datatablesize = n;
  1041. // }
  1042. // // =================================================================================================================
  1043. //
  1044. // if(datatable_found==TRUE)
  1045. // if(datatablesize>0)
  1046. // ;
  1047. //
  1048. //
  1049. // while( IsWhiteChar( *str ) ) str++; // -- ïðîïóñê WHITE
  1050. //
  1051. // if( *str == GPIB_CHAR_MANDATORY_IEEE488_SIGN || (*str == GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN && (str++)) ) Search = root;
  1052. // /* ïðîâåðÿì, àáñîëþòíûé ëè ïóòü çàäàí
  1053. // FAQ: åñëè ïóòü àáñ., îí èìååò äâîåòî÷èå â íà÷àëå. Åñëè åñòü äâîåòî÷èå,
  1054. // òî ïåðâîå óñëîâèå â if() âûïîëíèòñÿ è âûïîëíèòñÿ âòîðîå,
  1055. // êîòîðîå ïî ñóòè ïðîñòî ñäâèíåò óêàçàòåëü str òàê, ÷òîáû èñêëþ÷èòü äâîåòî÷èå
  1056. // ïîèñê áóäåò ïðîèçâåäåí â root, òàê êàê ïóñòü àáñîëþòíûé */
  1057. //
  1058. // udi->usbtmcGpib.gpib_search = Search;
  1059. // udi->usbtmcGpib.sgpib_current = str;
  1060. //
  1061. //
  1062. //
  1063. // if(NULL != (rc=parse( udi,str, FALSE, cmde)))
  1064. // { // -- îáðàáîòêà îäíîé ñîñòàâíîé êîììàíäû â ñòðîêå
  1065. //
  1066. // ret_val++; // -- èíêðåìåíòèðóåì ñ÷åò÷èê âûïîëíåííûõ êîììàíä
  1067. //
  1068. // }
  1069. // else
  1070. // {
  1071. //
  1072. // if( SubPointers( cmde, str ) > 0 ) // if( INT(cmde) - INT(str) > 0 )
  1073. // { char * tmpe = cmde;
  1074. // if( IsEndOfLine(*tmpe) ) tmpe--;
  1075. // while( IsWhiteChar(*tmpe) ) tmpe--;
  1076. // if(usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE ,ERROR_USBTMC_INVALID_HEADER, "'", 1))
  1077. // if(usbtmc_RaiseError_CatDescription( udi, str , SubPointers( tmpe+1, str ) )) // strl ïîäñ÷èòûâàåòñÿ â íà÷àëå ô-èè. -1 -ýòî ïðîïóñê 0x0A; àëñî: (INT(tmpe+1) - INT(str)) ===> SubPointers( tmpe+1, str )
  1078. // usbtmc_RaiseError_CatDescription( udi, "'", 1 );
  1079. //
  1080. // }
  1081. //
  1082. // rc= Search;
  1083. // }
  1084. //
  1085. //
  1086. //
  1087. // if( semicolon != NULL ) { // -- åñëè íå NULL, çíà÷èò åñòü åùå íå âûïîëíåííûå êîìàíäû â ñòðîêå
  1088. // str = (++semicolon); // -- ïåðåõîä ê ñëåäóþùåé êîììàíäå â ñòðîêå, èñêëþ÷àÿÿ òî÷êó ñ çàïÿòîé
  1089. // if( *str != GPIB_CHAR_SCPI_SUBSYS_SEPARATOR_SIGN ) // -- åñëè êîììàíäà íå àáñîëþòíàÿ è ïóòü åå îïóùåí
  1090. // Search = rc; // -- óêàçûâàåì ïóòü ïîèñêà íà ïîñëåäíèé ïóòü, ãäå áûëà âûïîëíåíà êîììàíäà
  1091. // } else break; // -- åñëè NULL âûõîäèì, íåò áîëüøå êîììàíä â ñòðîêå
  1092. //
  1093. // }
  1094. //
  1095. // return ret_val; // -- âîçâðàùàåì êîëè÷åñòâî ðàñïîçíàííûõ êîììàíä
  1096. //}
  1097. // =========================================== ÎÁÐÀÁÎÒ×ÈÊÈ ======================================================
  1098. unsigned int GPIB_Default_Handler( USB_DEVICE_INFO * udi, QUEUE * pQParameters, BOOL request )
  1099. {
  1100. // 27/08/18
  1101. GPIB_RaiseStandartError( udi,
  1102. ERROR_GPIB_UNCOMPLETE_COMMAND,
  1103. NULL,
  1104. errClass_Command // == invalid header detected
  1105. );
  1106. /*
  1107. GPIB_RaiseStandartError( udi,
  1108. ERROR_GPIB_UNCOMPLETE_COMMAND,
  1109. NULL,
  1110. GPIB_ERROR_ID_COR | request
  1111. );
  1112. */
  1113. return 0;
  1114. }
  1115. // ====================================================================================================
  1116. // GPIB_EnumParameters:
  1117. // Processes the @pParamString with @length length and parses the command parameters.
  1118. // The following SCPI types are supported:
  1119. // - NR1, NR2, NR3
  1120. // - Mnemonic (character)
  1121. // - Strings
  1122. // - binary DataBlock
  1123. // All the parameters are packed into the @pQueue
  1124. // In case an error occurred, the function interrupts processing and return an error code.
  1125. // Note: in case of error the @pQueue is already modified.
  1126. // @pParamString - the source string
  1127. // @length - the length of @pParamString
  1128. // @pQueue - the queue to pack parameters in
  1129. // @pEnd - (NOT IMPLEMENTED!) optional pointer to store the end of parsed string after parsing. Can be NULL.
  1130. // If @pEnd isn't NULL, it will contain the pointer to the character after the lastest parsed character in @pParamString.
  1131. // Return: error code (negative) or number of parsed parameters (positive)
  1132. int GPIB_EnumParameters( const char * pParamString, size_t length, QUEUE * pQueue, const char ** pEnd )
  1133. {
  1134. if( NULL == pParamString || 0 == length || NULL == pQueue )
  1135. return -1;
  1136. if( NULL != pEnd )
  1137. {
  1138. *pEnd = NULL; // not implemented
  1139. }
  1140. int rval = 0;
  1141. int nsys = 0; // numeric system
  1142. size_t count = 0; // amount of parameters enumerated
  1143. eQuoteMode_t qMode; // quoting mode (single/double)
  1144. eParameterType_t eParamType = eParTypeNone; // parameter type
  1145. const char * pParamStart = NULL; // the parameter start pointer in @pParamString
  1146. const char * end = NULL;
  1147. BOOL bSeparator = FALSE; // flag: separator found
  1148. while( length > 0 ) // parameter search cycle
  1149. {
  1150. bSeparator = FALSE; // clear flag: allow a separator character in this search cycle
  1151. // ---------------------------------------------------------------------
  1152. while( length > 0 ) // white characters skipping cycle
  1153. {
  1154. // check current character: is it a white character?
  1155. if( IsWhiteChar( *pParamString ) )
  1156. {
  1157. // yes. skip this character
  1158. pParamString++;
  1159. length--;
  1160. // check the next character
  1161. continue;
  1162. }
  1163. // check current character: is this a end-of-line character?
  1164. if( IsEndOfLine( *pParamString ) )
  1165. {
  1166. // yes. skip this character
  1167. pParamString++;
  1168. length--;
  1169. // if the line ends and the length is still greater than zero:
  1170. // it is an error condition
  1171. if( length > 0 )
  1172. {
  1173. // interrupt all procedures and exit
  1174. rval = (-1);
  1175. goto L_EnumParameters_EXIT;
  1176. }
  1177. // Okay, @length is 0.
  1178. // The next "continue" will interrupt the main cycle.
  1179. // But let's check the @bSeparator.
  1180. // If @bSeparator is TRUE, it means a trailing separator found.
  1181. if( bSeparator )
  1182. {
  1183. // error: trailing separator found
  1184. rval = (-2);
  1185. goto L_EnumParameters_EXIT;
  1186. }
  1187. // exit the main cycle, because @length == 0
  1188. goto L_EnumParameters_EXIT;
  1189. }
  1190. // check if this character is an argument separator character (by default is ',')
  1191. if( GPIB_CHAR_ARGSEPARATOR_SIGN == *pParamString )
  1192. {
  1193. // Yes: it is an argument separator
  1194. // check if the separator is allowed now
  1195. // If @bSeparator is already TRUE then it means the separator is disallowed
  1196. // Otherwise, the separator is allowed.
  1197. if( ! bSeparator )
  1198. {
  1199. bSeparator = TRUE; // set the flag: the separator is found in current cycle
  1200. pParamString++; // skip the character
  1201. length--;
  1202. // check the next character
  1203. continue;
  1204. }
  1205. else
  1206. {
  1207. // No: the separator is already found before.
  1208. // Extra separator found: error
  1209. // interrupt all procedures and exit
  1210. rval = (-3);
  1211. goto L_EnumParameters_EXIT;
  1212. }
  1213. }
  1214. else
  1215. {
  1216. // No: it's neither a white character or separator character
  1217. // interrupt the skipping cycle.
  1218. break;
  1219. }
  1220. } // :while( length > 0 )
  1221. // ---------------------------------------------------------------------
  1222. // White character are skipped.
  1223. // An argument separator processed.
  1224. // It is assumed that the next character is an argument.
  1225. // check if the argument separator presents between arguments
  1226. if( (count > 0) && (!bSeparator) )
  1227. {
  1228. // In this point @bSeparator must be TRUE in order all the arguments
  1229. // must be separated.
  1230. // The only one exception: @count == 0, it means neither argument or
  1231. // or separator found yet in the string.
  1232. // interrupt all procedures and exit
  1233. rval = (-4);
  1234. goto L_EnumParameters_EXIT;
  1235. }
  1236. // ---------------------------------------------------------------------
  1237. // Analyze the current character and check for the string type
  1238. switch( *pParamString )
  1239. {
  1240. // the quoted string in single quotes
  1241. case GPIB_CHAR_SINGLEQUOTE_SIGN: qMode = eqmSingle; break;
  1242. // the quoted string in double quotes
  1243. case GPIB_CHAR_DOUBLEQUOTE_SIGN: qMode = eqmDouble; break;
  1244. // not quoted argument
  1245. default: qMode = eqmNone;
  1246. }
  1247. //
  1248. // ---------------------------------------------------------------------
  1249. //
  1250. // Let's determine the parameter type
  1251. //
  1252. size_t nParamSize; // parameter size in [characters]
  1253. // if the quoted string is found:
  1254. if( IsQuote( *pParamString , qMode ) )
  1255. {
  1256. // search for the end of quoted string
  1257. end = GPIB_GetStringEnd( pParamString, length );
  1258. // check if the string is closed
  1259. if( NULL == end )
  1260. {
  1261. // error: unclosed quoted string
  1262. // interrupt all procedures and exit
  1263. rval = (-5);
  1264. goto L_EnumParameters_EXIT;
  1265. }
  1266. // calculate the parameter size in characters
  1267. nParamSize = (size_t)SubPointers( end, pParamString );
  1268. // set the parameter start pointer
  1269. pParamStart = pParamString;
  1270. // skip the parameter's body in the parent string.
  1271. length -= nParamSize;
  1272. pParamString += nParamSize;
  1273. // And at last, set the parameter type to @eParamType. It is string.
  1274. eParamType = eParTypeString;
  1275. // modify the parameter value: "STR" -> STR
  1276. // delete quotes:
  1277. pParamStart++; nParamSize-=2;
  1278. // stop analyzing and process the parameter
  1279. goto L_EnumParameters_END;
  1280. }
  1281. // ---------------------------------------------------------------------
  1282. // Here: parameter is not a string parameter for sure
  1283. // Maybe it is a mnemonic, numeric or datablock parameter
  1284. {
  1285. // Firstly check for DataBlock format:
  1286. // @dataBlockError will store the error code of @IsDataBlock() function
  1287. int dataBlockCode = err_IsDataBlock_Success;
  1288. // Check the datablock
  1289. if( IsDataBlock( pParamString, length, &nParamSize, &dataBlockCode ) )
  1290. {
  1291. // datablock detected.
  1292. // Now @nParamSize is the size of whole datablock segment
  1293. // set the parameter start pointer
  1294. pParamStart = pParamString;
  1295. // --------------------------------------------------------
  1296. // Note: @nParamSize is whole size of data block parameter,
  1297. // including the signature and service fields.
  1298. // --------------------------------------------------------
  1299. // skip the parameter's body in the parent string.
  1300. pParamString += nParamSize;
  1301. length -= nParamSize;
  1302. // And at last, set the parameter type to @eParamType. It is datablock.
  1303. eParamType = eParTypeDatablock;
  1304. // modify the parameter value:
  1305. // Set @pParamStart to the start of binary payload
  1306. // Set @nParamSize to the binary payload size (@dataBlockCode)
  1307. nParamSize = dataBlockCode;
  1308. pParamStart = pParamString - nParamSize;
  1309. // stop analyzing and process the parameter
  1310. goto L_EnumParameters_END;
  1311. }
  1312. else
  1313. {
  1314. switch( dataBlockCode )
  1315. {
  1316. // datablock not detected
  1317. case err_IsDataBlock_NotFound:
  1318. break;
  1319. // datablock signature detected.
  1320. // Maybe it is not datablock,
  1321. // Maybe it is corrupted parameter
  1322. case err_IsDataBlock_Invalid:
  1323. case err_IsDataBlock_Trimmed:
  1324. case err_IsDataBlock_Huge:
  1325. #if 0
  1326. // hmmm. is it error?
  1327. rval = (-6);
  1328. goto L_EnumParameters_EXIT;
  1329. #endif
  1330. break;
  1331. }
  1332. }
  1333. }
  1334. // ---------------------------------------------------------------------
  1335. // Here: parameter is neither a string parameter or datablock parameter
  1336. // Maybe it is a mnemonic or numeric
  1337. // Ok, search for the end of the parameter
  1338. // search for the end of parameter
  1339. // @GPIB_GetParameterEnd searches til the first white character or the end-of-line.
  1340. end = GPIB_GetParameterEnd( pParamString, length );
  1341. // check if the end of the parameter is found
  1342. if( NULL == end )
  1343. {
  1344. // error: endless parameter
  1345. // interrupt all procedures and exit
  1346. rval = (-7);
  1347. goto L_EnumParameters_EXIT;
  1348. }
  1349. {
  1350. // calculate the parameter size in characters
  1351. nParamSize = (size_t)SubPointers( end, pParamString );
  1352. // set the parameter start pointer
  1353. pParamStart = pParamString;
  1354. // skip the parameter's body in the parent string.
  1355. length -= nParamSize;
  1356. pParamString += nParamSize;
  1357. }
  1358. // Check for "MNEMONIC" parameter type
  1359. if( IsCharacter( *pParamStart ) )
  1360. {
  1361. // First character is an "alhpa-character":
  1362. // So, the parameter will be considered as "MNEMONIC"
  1363. // Validate the parameter format:
  1364. if( ! GPIB_StrChkFormat( pParamStart, nParamSize, eSCM_MNEMONIC ) )
  1365. {
  1366. // invalid parameter format: some invalid characters found
  1367. // interrupt all procedures and exit
  1368. rval = (-8);
  1369. goto L_EnumParameters_EXIT;
  1370. }
  1371. // And at last, set the parameter type to @eParamType. It is MNEMONIC (character-parameter).
  1372. eParamType = eParTypeChar;
  1373. // stop analyzing and process the parameter
  1374. goto L_EnumParameters_END;
  1375. }
  1376. // ---------------------------------------------------------------------
  1377. // Here: parameter is numeric: NR1, NR2 or NR3 (SCPI types)
  1378. // Check for NR1:
  1379. nsys = 0; // numeric system
  1380. // Try to determine the numeric system
  1381. if( IsNumericSystem(pParamStart) )
  1382. {
  1383. // NR1, numeric system specified
  1384. // Numeric system detected: get the numeric system base
  1385. nsys = GetNumericSystemBase( pParamStart );
  1386. switch( nsys )
  1387. {
  1388. // unknown system
  1389. case 0:
  1390. rval = (-9);
  1391. goto L_EnumParameters_EXIT;
  1392. break;
  1393. // Binary system
  1394. case 2: if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_BIN ) )
  1395. {
  1396. // Invalid character for binary system
  1397. rval = (-10);
  1398. goto L_EnumParameters_EXIT;
  1399. }
  1400. break;
  1401. // Octal system
  1402. case 8: if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_OCT ) )
  1403. {
  1404. // Invalid character for octal system
  1405. rval = (-10);
  1406. goto L_EnumParameters_EXIT;
  1407. }
  1408. break;
  1409. // Hexademical system
  1410. case 16:if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_HEX ) )
  1411. {
  1412. // Invalid character for hexademical system
  1413. rval = (-10);
  1414. goto L_EnumParameters_EXIT;
  1415. }
  1416. break;
  1417. }
  1418. // And at last, set the parameter type to @eParamType. It is NR1 (numeric, integer)
  1419. eParamType = eParTypeNR1;
  1420. // stop analyzing and process the parameter
  1421. goto L_EnumParameters_END;
  1422. }
  1423. // ---------------------------------------------------------------------
  1424. // Here: parameter is numeric: NR1, NR2 or NR3 (SCPI types)
  1425. // Check for NR1
  1426. if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_DEC ) )
  1427. {
  1428. eParamType = eParTypeNR1;
  1429. // stop analyzing and process the parameter
  1430. goto L_EnumParameters_END;
  1431. }
  1432. // Check for NR2
  1433. if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_FLOAT ) )
  1434. {
  1435. eParamType = eParTypeNR2;
  1436. // stop analyzing and process the parameter
  1437. goto L_EnumParameters_END;
  1438. }
  1439. // Check for NR3
  1440. if( GPIB_StrChkFormat( pParamStart,nParamSize,eSCM_EXP ) )
  1441. {
  1442. eParamType = eParTypeNR2;
  1443. // stop analyzing and process the parameter
  1444. goto L_EnumParameters_END;
  1445. }
  1446. // ---------------------------------------------------------------------
  1447. // No valid format detected
  1448. // Here: invalid parameter format
  1449. // Invalid character for binary system
  1450. rval = (-11);
  1451. goto L_EnumParameters_EXIT;
  1452. // ---------------------------------------------------------------------
  1453. L_EnumParameters_END:
  1454. // Valid format detected:
  1455. // @pParamStart - the beginning of parameter
  1456. // @nParamSize - the size of parameter
  1457. // @eParamType - the type of parameter
  1458. // -------------------------------------------------------------------------
  1459. // Push the parameter into the parameters queue
  1460. {
  1461. BYTE pkdParamType = eParamType; // 1-byte packed parameter type
  1462. // push the type
  1463. if( !queue_add( pQueue, &pkdParamType, sizeof(pkdParamType) ) )
  1464. {
  1465. // parameters queue overflow
  1466. rval = (-12);
  1467. goto L_EnumParameters_EXIT;
  1468. }
  1469. // push the string value
  1470. if( !queue_cat( pQueue, pParamStart, nParamSize ) )
  1471. {
  1472. // parameters queue overflow
  1473. rval = (-13);
  1474. goto L_EnumParameters_EXIT;
  1475. }
  1476. }
  1477. // increment amount of parsed parameters
  1478. count++;
  1479. }
  1480. rval = count;
  1481. L_EnumParameters_EXIT:
  1482. return rval;
  1483. }
  1484. // ====================================================================================
  1485. eChrz_t GPIB_GetChrzTableId( const char * pParamText, size_t nTextLen )
  1486. {
  1487. eChrz_t ID = eCh_MAX;
  1488. if( 0 == strncmp( pParamText, "FACT", nTextLen ) && 4 == nTextLen ) ID = eChFactory;
  1489. else
  1490. if( 0 == strncmp( pParamText, "FACTORY",nTextLen ) && 7 == nTextLen ) ID = eChFactory;
  1491. else
  1492. if( 0 == strncmp( pParamText, "USER1", nTextLen ) && 5 == nTextLen ) ID = eChUser1;
  1493. else
  1494. if( 0 == strncmp( pParamText, "USER2", nTextLen ) && 5 == nTextLen ) ID = eChUser2;
  1495. else
  1496. if( 0 == strncmp( pParamText, "USER3", nTextLen ) && 5 == nTextLen ) ID = eChUser3;
  1497. return ID;
  1498. }
  1499. // ====================================================================================
  1500. ePortId_t GPIB_GetPortId( const char * pParamText, size_t nTextLen )
  1501. {
  1502. ePortId_t ID = ePortId_MAX;
  1503. if( 0 == strncmp( pParamText, "A", nTextLen ) && 1 == nTextLen ) ID = ePortId_A;
  1504. else
  1505. if( 0 == strncmp( pParamText, "B", nTextLen ) && 1 == nTextLen ) ID = ePortId_B;
  1506. else
  1507. if( 0 == strncmp( pParamText, "C", nTextLen ) && 1 == nTextLen ) ID = ePortId_C;
  1508. else
  1509. if( 0 == strncmp( pParamText, "D", nTextLen ) && 1 == nTextLen ) ID = ePortId_D;
  1510. return ID;
  1511. }
  1512. // ====================================================================================
  1513. ePortComb_t GPIB_GetPortComb( const char * pParamText, size_t nTextLen )
  1514. {
  1515. ePortComb_t ID = ePortComb_UNDEFINED;
  1516. if( 0 == strncmp( pParamText, "A", nTextLen ) && 1 == nTextLen ) ID = ePortComb_A;
  1517. else
  1518. if( 0 == strncmp( pParamText, "B", nTextLen ) && 1 == nTextLen ) ID = ePortComb_B;
  1519. else
  1520. if( 0 == strncmp( pParamText, "C", nTextLen ) && 1 == nTextLen ) ID = ePortComb_C;
  1521. else
  1522. if( 0 == strncmp( pParamText, "D", nTextLen ) && 1 == nTextLen ) ID = ePortComb_D;
  1523. else
  1524. if( 0 == strncmp( pParamText, "AB", nTextLen ) && 2 == nTextLen ) ID = ePortComb_AB;
  1525. else
  1526. if( 0 == strncmp( pParamText, "AC", nTextLen ) && 2 == nTextLen ) ID = ePortComb_AC;
  1527. else
  1528. if( 0 == strncmp( pParamText, "AD", nTextLen ) && 2 == nTextLen ) ID = ePortComb_AD;
  1529. else
  1530. if( 0 == strncmp( pParamText, "BC", nTextLen ) && 2 == nTextLen ) ID = ePortComb_BC;
  1531. else
  1532. if( 0 == strncmp( pParamText, "BD", nTextLen ) && 2 == nTextLen ) ID = ePortComb_BD;
  1533. else
  1534. if( 0 == strncmp( pParamText, "CD", nTextLen ) && 2 == nTextLen ) ID = ePortComb_CD;
  1535. else
  1536. if( 0 == strncmp( pParamText, "CHEC",nTextLen) && 4 == nTextLen ) ID = ePortComb_CHECK;
  1537. else
  1538. if( 0 == strncmp( pParamText, "CHECK",nTextLen)&& 5 == nTextLen ) ID = ePortComb_CHECK;
  1539. return ID;
  1540. }
  1541. // ====================================================================================
  1542. ePortStateId_t GPIB_GetPortStateId( const char * pParamText, size_t nTextLen )
  1543. {
  1544. ePortStateId_t ID = ePortStateId_UNDEFINED;
  1545. if( 4 == nTextLen && 0 == strncmp( pParamText, "SHOR", nTextLen ) ) ID = ePortStateId_Short;
  1546. else
  1547. if( 5 == nTextLen && 0 == strncmp( pParamText, "SHORT", nTextLen ) ) ID = ePortStateId_Short;
  1548. else
  1549. if( 4 == nTextLen && 0 == strncmp( pParamText, "OPEN", nTextLen ) ) ID = ePortStateId_Open;
  1550. else
  1551. if( 4 == nTextLen && 0 == strncmp( pParamText, "LOAD", nTextLen ) ) ID = ePortStateId_Load;
  1552. else
  1553. if( 5 == nTextLen && 0 == strncmp( pParamText, "OPEN2", nTextLen ) ) ID = ePortStateId_Open2;
  1554. else
  1555. if( 5 == nTextLen && 0 == strncmp( pParamText, "LOAD2", nTextLen ) ) ID = ePortStateId_Load2;
  1556. else
  1557. if( 3 == nTextLen && 0 == strncmp( pParamText, "S11", nTextLen ) ) ID = ePortStateId_S11;
  1558. else
  1559. if( 3 == nTextLen && 0 == strncmp( pParamText, "S12", nTextLen ) ) ID = ePortStateId_S12;
  1560. else
  1561. if( 3 == nTextLen && 0 == strncmp( pParamText, "S13", nTextLen ) ) ID = ePortStateId_S13;
  1562. else
  1563. if( 3 == nTextLen && 0 == strncmp( pParamText, "S14", nTextLen ) ) ID = ePortStateId_S14;
  1564. else
  1565. if( 3 == nTextLen && 0 == strncmp( pParamText, "S21", nTextLen ) ) ID = ePortStateId_S21;
  1566. else
  1567. if( 3 == nTextLen && 0 == strncmp( pParamText, "S22", nTextLen ) ) ID = ePortStateId_S22;
  1568. else
  1569. if( 3 == nTextLen && 0 == strncmp( pParamText, "S23", nTextLen ) ) ID = ePortStateId_S23;
  1570. else
  1571. if( 3 == nTextLen && 0 == strncmp( pParamText, "S24", nTextLen ) ) ID = ePortStateId_S24;
  1572. else
  1573. if( 3 == nTextLen && 0 == strncmp( pParamText, "S31", nTextLen ) ) ID = ePortStateId_S31;
  1574. else
  1575. if( 3 == nTextLen && 0 == strncmp( pParamText, "S32", nTextLen ) ) ID = ePortStateId_S32;
  1576. else
  1577. if( 3 == nTextLen && 0 == strncmp( pParamText, "S33", nTextLen ) ) ID = ePortStateId_S33;
  1578. else
  1579. if( 3 == nTextLen && 0 == strncmp( pParamText, "S34", nTextLen ) ) ID = ePortStateId_S34;
  1580. else
  1581. if( 3 == nTextLen && 0 == strncmp( pParamText, "S41", nTextLen ) ) ID = ePortStateId_S41;
  1582. else
  1583. if( 3 == nTextLen && 0 == strncmp( pParamText, "S42", nTextLen ) ) ID = ePortStateId_S42;
  1584. else
  1585. if( 3 == nTextLen && 0 == strncmp( pParamText, "S43", nTextLen ) ) ID = ePortStateId_S43;
  1586. else
  1587. if( 3 == nTextLen && 0 == strncmp( pParamText, "S44", nTextLen ) ) ID = ePortStateId_S44;
  1588. return ID;
  1589. }
  1590. // ====================================================================================
  1591. /*
  1592. EPORT GPIB_GetPortID( char * sQueueParameter, unsigned int dwQueueParameterSize )
  1593. {
  1594. EPORT port = ePORT_NONE;
  1595. if(0==strncmp(sQueueParameter+1,"A",dwQueueParameterSize-1) && dwQueueParameterSize>1) port = ePORT_A;
  1596. else
  1597. if(0==strncmp(sQueueParameter+1,"B",dwQueueParameterSize-1) && dwQueueParameterSize>1) port = ePORT_B;
  1598. else
  1599. if(0==strncmp(sQueueParameter+1,"AB",dwQueueParameterSize-1) && dwQueueParameterSize>2)port = ePORT_AB;
  1600. return port;
  1601. }
  1602. */
  1603. // ====================================================================================
  1604. /*
  1605. ESTATE GPIB_GetKeystateID( char * sQueueParameter, unsigned int dwQueueParameterSize, BOOL ExpandFormat )
  1606. {
  1607. ESTATE state = eSTATE_NONE;
  1608. if(0==strncmp(sQueueParameter+1,"OPEN",dwQueueParameterSize-1) && dwQueueParameterSize>4) state = eSTATE_OPEN;
  1609. else
  1610. if(0==strncmp(sQueueParameter+1,"LOAD",dwQueueParameterSize-1) && dwQueueParameterSize>4) state = eSTATE_LOAD;
  1611. else
  1612. if(0==strncmp(sQueueParameter+1,"SHORT",dwQueueParameterSize-1) && dwQueueParameterSize>4) state = eSTATE_SHORT; //SHOR==SHORt
  1613. else
  1614. if(0==strncmp(sQueueParameter+1,"OPEN2",dwQueueParameterSize-1) && dwQueueParameterSize>5) state = eSTATE_OPEN2;
  1615. else
  1616. if(0==strncmp(sQueueParameter+1,"LOAD2",dwQueueParameterSize-1) && dwQueueParameterSize>5) state = eSTATE_LOAD2;
  1617. else
  1618. if(ExpandFormat == FALSE && 0==strncmp(sQueueParameter+1,"THRU",dwQueueParameterSize-1) && dwQueueParameterSize>4) state = eSTATE_THRU;
  1619. else
  1620. if(ExpandFormat == FALSE && 0==strncmp(sQueueParameter+1,"ATT",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_ATTEN;
  1621. else
  1622. if(ExpandFormat)
  1623. if(0==strncmp(sQueueParameter+1,"T11",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_T11;
  1624. else
  1625. if(0==strncmp(sQueueParameter+1,"T12",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_T12;
  1626. else
  1627. if(0==strncmp(sQueueParameter+1,"T21",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_T21;
  1628. else
  1629. if(0==strncmp(sQueueParameter+1,"T22",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_T22;
  1630. else
  1631. if(0==strncmp(sQueueParameter+1,"A11",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_A11;
  1632. else
  1633. if(0==strncmp(sQueueParameter+1,"A12",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_A12;
  1634. else
  1635. if(0==strncmp(sQueueParameter+1,"A21",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_A21;
  1636. else
  1637. if(0==strncmp(sQueueParameter+1,"A22",dwQueueParameterSize-1) && dwQueueParameterSize>3) state = eSTATE_A22;
  1638. else
  1639. state = eSTATE_NONE;
  1640. return state;
  1641. }
  1642. */
  1643. // ====================================================================================
  1644. unsigned int GPIB_RaiseStandartError( USB_DEVICE_INFO * udi,
  1645. unsigned int errCode, // error code
  1646. const char * pDescription, // error description
  1647. GPIB_ErrorClass_t errClass // error class
  1648. )
  1649. {
  1650. const char * pStrCurrentCmd = udi->usbtmcGpib.sgpib_current;
  1651. // search for the command header's end
  1652. while( !(IsWhiteChar( *pStrCurrentCmd ) || IsEndOfLine( *pStrCurrentCmd )) )
  1653. {
  1654. pStrCurrentCmd++;
  1655. }
  1656. size_t nCmdLength = SubPointers( pStrCurrentCmd, udi->usbtmcGpib.sgpib_current);
  1657. pStrCurrentCmd = udi->usbtmcGpib.sgpib_current;
  1658. switch( errCode )
  1659. {
  1660. case ERROR_GPIB_BUFFER_OVERFLOW:
  1661. {
  1662. if( errClass_Autodetect == errClass )
  1663. errClass = errClass_Execution;
  1664. //ERROR_USBTMC_BUFFER_OVERFLOW_IN
  1665. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_INTERNAL, " in '", 5 ) )
  1666. {
  1667. errCode = 0; break;
  1668. }
  1669. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1670. {
  1671. errCode = 0; break;
  1672. }
  1673. if( !usbtmc_RaiseError_CatDescription( udi, "': ", 3 ) )
  1674. {
  1675. errCode = 0; break;
  1676. }
  1677. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1678. {
  1679. errCode = 0; break;
  1680. }
  1681. }
  1682. break;
  1683. case ERROR_GPIB_DATA_NOT_FOUND:
  1684. {
  1685. if( errClass_Autodetect == errClass )
  1686. errClass = errClass_Execution;
  1687. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_DATANOTFOUND, " in '", 5 ) )
  1688. {
  1689. errCode = 0; break;
  1690. }
  1691. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1692. {
  1693. errCode = 0; break;
  1694. }
  1695. if( !usbtmc_RaiseError_CatDescription( udi, "': ", 3 ) )
  1696. {
  1697. errCode = 0; break;
  1698. }
  1699. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1700. {
  1701. errCode = 0; break;
  1702. }
  1703. /*
  1704. if(usbtmc_RaiseError( udi, ErrorIdetnificator, ERROR_USBTMC_DATANOTFOUND, "", 0 ) )
  1705. {
  1706. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1707. {
  1708. errCode = 0;
  1709. }
  1710. }
  1711. else
  1712. errCode = 0;*/
  1713. }
  1714. break;
  1715. case ERROR_GPIB_THERMDATA_NOT_FOUND:
  1716. {
  1717. if( errClass_Autodetect == errClass )
  1718. errClass = errClass_Execution;
  1719. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_NOTHERMCOMPDATA, " in '", 5 ) )
  1720. {
  1721. errCode = 0; break;
  1722. }
  1723. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1724. {
  1725. errCode = 0; break;
  1726. }
  1727. if( !usbtmc_RaiseError_CatDescription( udi, "': ", 3 ) )
  1728. {
  1729. errCode = 0; break;
  1730. }
  1731. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1732. {
  1733. errCode = 0; break;
  1734. }
  1735. /*if( !usbtmc_RaiseError( udi, ErrorIdetnificator, ERROR_USBTMC_NOTHERMCOMPDATA, pDescription, strlen(pDescription) ) )
  1736. {
  1737. errCode = 0;
  1738. }*/
  1739. }
  1740. break;
  1741. case ERROR_GPIB_UNCOMPLETE_COMMAND:
  1742. {
  1743. if( errClass_Autodetect == errClass )
  1744. errClass = errClass_Command;
  1745. if(usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_INVALID_HEADER, "'", 1 ))
  1746. {
  1747. if( usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1748. {
  1749. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1 ) )
  1750. {
  1751. errCode = 0;
  1752. }
  1753. }
  1754. else
  1755. errCode = 0;
  1756. }
  1757. else
  1758. errCode = 0;
  1759. }
  1760. break;
  1761. /*
  1762. case ERROR_GPIB_PARAMETER_NOT_SUPPORTED:
  1763. {
  1764. if( errClass_Autodetect == errClass )
  1765. errClass = errClass_Execution;
  1766. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_PARAMETER, " in '", 5 ) )
  1767. {
  1768. errCode = 0; break;
  1769. }
  1770. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1771. {
  1772. errCode = 0; break;
  1773. }
  1774. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1 ) )
  1775. {
  1776. errCode = 0; break;
  1777. }
  1778. // if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1779. // {
  1780. // errCode = 0; break;
  1781. // }
  1782. // if(usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_PARAMETER, "'", 1 ))
  1783. // {
  1784. // if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1785. // {
  1786. // errCode = 0;
  1787. // }
  1788. // }
  1789. // else
  1790. // errCode = 0;
  1791. }
  1792. break;
  1793. */
  1794. case ERROR_GPIB_TRIGGER_IGNORED:
  1795. {
  1796. if( errClass_Autodetect == errClass )
  1797. errClass = errClass_Command;
  1798. if(usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_TRIGGERIGNORED, "'", 1 ))
  1799. {
  1800. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1801. {
  1802. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1) )
  1803. {
  1804. errCode = 0;
  1805. }
  1806. }
  1807. else
  1808. errCode = 0;
  1809. }
  1810. else
  1811. errCode = 0;
  1812. }
  1813. break;
  1814. case ERROR_GPIB_REQUEST_ONLY_SUPPORT:
  1815. {
  1816. if( errClass_Autodetect == errClass )
  1817. errClass = errClass_Command;
  1818. if(usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_REQUESTONLY, "'", 1 ))
  1819. {
  1820. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1821. {
  1822. if( !usbtmc_RaiseError_CatDescription( udi, "': request only supported", 25 ) )
  1823. {
  1824. errCode = 0;
  1825. }
  1826. }
  1827. else
  1828. errCode = 0;
  1829. }
  1830. else
  1831. errCode = 0;
  1832. }
  1833. break;
  1834. case ERROR_GPIB_ARRAY_CORRUPTED:
  1835. {
  1836. if( errClass_Autodetect == errClass )
  1837. errClass = errClass_Execution;
  1838. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_ARRAY_CORRUPTED, "in '", 4 ) )
  1839. {
  1840. errCode = 0; break;
  1841. }
  1842. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1843. {
  1844. errCode = 0; break;
  1845. }
  1846. if( !usbtmc_RaiseError_CatDescription( udi, "': ", 3 ) )
  1847. {
  1848. errCode = 0; break;
  1849. }
  1850. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1851. {
  1852. errCode = 0; break;
  1853. }
  1854. /*
  1855. if(usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_ARRAY_CORRUPTED, "'", 1 ))
  1856. {
  1857. if(usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ))
  1858. //if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1859. {
  1860. if( !usbtmc_RaiseError_CatDescription( udi, "': invalid checksumm", 20 ) )
  1861. {
  1862. errCode = 0;
  1863. }
  1864. }
  1865. else
  1866. errCode = 0;
  1867. }
  1868. else
  1869. errCode = 0; */
  1870. }
  1871. break;
  1872. /*
  1873. case ERROR_GPIB_HEADER_CORRUPTED:
  1874. {
  1875. if(usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_HEADER_CORRUPTED, "'", 1 ))
  1876. {
  1877. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1878. {
  1879. if( !usbtmc_RaiseError_CatDescription( udi, "': header corrupted", 18 ) )
  1880. {
  1881. errCode = 0;
  1882. }
  1883. }
  1884. else
  1885. errCode = 0;
  1886. }
  1887. else
  1888. errCode = 0;
  1889. }
  1890. break; */
  1891. case ERROR_GPIB_TOO_MANY_REQUESTS:
  1892. {
  1893. if( errClass_Autodetect == errClass )
  1894. errClass = errClass_Device;
  1895. if(usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_TOOMANY_REQUESTS, "'", 1 ))
  1896. {
  1897. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1898. {
  1899. if( !usbtmc_RaiseError_CatDescription( udi, "')", 2) )
  1900. {
  1901. errCode = 0;
  1902. }
  1903. }
  1904. else
  1905. errCode = 0;
  1906. }
  1907. else
  1908. errCode = 0;
  1909. }
  1910. break;
  1911. case ERROR_GPIB_COMMAND_ONLY_SUPPORT:
  1912. {
  1913. if( errClass_Autodetect == errClass )
  1914. errClass = errClass_Command;
  1915. if(usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_COMMANDONLY, "'", 1 ))
  1916. {
  1917. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1918. {
  1919. if( !usbtmc_RaiseError_CatDescription( udi, "': request is unexpected", 24) )
  1920. {
  1921. errCode = 0;
  1922. }
  1923. }
  1924. else
  1925. errCode = 0;
  1926. }
  1927. else
  1928. errCode = 0;
  1929. }
  1930. break;
  1931. case ERROR_GPIB_INTERNAL:
  1932. {
  1933. if( errClass_Autodetect == errClass )
  1934. errClass = errClass_Device;
  1935. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_INTERNAL, " at command '", 13 ) )
  1936. {
  1937. errCode = 0; break;
  1938. }
  1939. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1940. {
  1941. errCode = 0; break;
  1942. }
  1943. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1 ) )
  1944. {
  1945. errCode = 0; break;
  1946. }
  1947. //usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_INTERNAL, ".", 1 );
  1948. }
  1949. break;
  1950. case ERROR_GPIB_INVALID_ENUM_PARAMETERS:
  1951. {
  1952. if( errClass_Autodetect == errClass )
  1953. errClass = errClass_Command;
  1954. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_PARAMETER, "in '", 4 ) )
  1955. {
  1956. errCode = 0; break;
  1957. }
  1958. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1959. {
  1960. errCode = 0; break;
  1961. }
  1962. if( !usbtmc_RaiseError_CatDescription( udi, "': parsing failed", 17 ) )
  1963. {
  1964. errCode = 0; break;
  1965. }
  1966. /*
  1967. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  1968. {
  1969. errCode = 0; break;
  1970. }
  1971. */
  1972. /*
  1973. if(usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_EXECUTION, " at '", 5 ))
  1974. {
  1975. if(usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength))
  1976. {
  1977. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1) )
  1978. {
  1979. errCode = 0;
  1980. }
  1981. }
  1982. else
  1983. errCode = 0;
  1984. }
  1985. else
  1986. errCode = 0;*/
  1987. }
  1988. break;
  1989. default:
  1990. {
  1991. if( errClass_Autodetect == errClass )
  1992. errClass = errClass_Command;
  1993. if( !usbtmc_RaiseError( udi, errClass, ERROR_USBTMC_PARAMETER, "in '", 4 ) )
  1994. {
  1995. errCode = 0; break;
  1996. }
  1997. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  1998. {
  1999. errCode = 0; break;
  2000. }
  2001. /*
  2002. if( !usbtmc_RaiseError_CatDescription( udi, "'", 1 ) )
  2003. {
  2004. errCode = 0; break;
  2005. }
  2006. */
  2007. /*
  2008. if( !usbtmc_RaiseError_CatDescription( udi, pDescription, strlen(pDescription) ) )
  2009. {
  2010. errCode = 0; break;
  2011. }
  2012. */
  2013. /*
  2014. if(usbtmc_RaiseError( udi,ErrorIdetnificator, ERROR_USBTMC_PARAMETER, "in '", 4 ))
  2015. {
  2016. if( !usbtmc_RaiseError_CatDescription( udi, pStrCurrentCmd, nCmdLength ) )
  2017. {
  2018. errCode = 0; // íå óäàëîñü çàïèñàòü îøèáêó, çíà÷èò è ïðîäîëæàòü (èäòè âî âòîðîé switch) íå ñòîèò
  2019. }
  2020. }
  2021. else
  2022. errCode = 0;*/
  2023. }
  2024. }
  2025. // ------------ 220 error ---------------------------------------------------------
  2026. switch( errCode )
  2027. {
  2028. case ERROR_GPIB_INVALID_PARAMETER_TYPE: // òàê êàê îøèáêà òèïà âîçíèêíåò ëèøü òîãäà, êîãäà get ñìîæåò äîñòàòü ïàðàìåòð è åãî òèï èç î÷åðåäè. À îí íåãî íå äîñòàòíåò, ïîòîìó ÷òî çà÷àñòóþ åìó íå õâàòèò ìåñòà â áóôåðå
  2029. case ERROR_GPIB_INVALID_PARAMETER:
  2030. {
  2031. if( !usbtmc_RaiseError_CatDescription( udi, "': invalid parameter", 20 ) )
  2032. {
  2033. errCode = 0;
  2034. }
  2035. }
  2036. break;
  2037. case ERROR_GPIB_WRONG_PARAMETERS_COUNT:
  2038. {
  2039. if( !usbtmc_RaiseError_CatDescription( udi, "': wrong parameters count", 25 ) )
  2040. {
  2041. errCode = 0;
  2042. }
  2043. }
  2044. break;
  2045. /*
  2046. case ERROR_GPIB_PARAMETER_NOT_SUPPORTED:
  2047. {
  2048. usbtmc_RaiseError_CatDescription( udi, "': parameter not supported", 26 );
  2049. }
  2050. break;
  2051. */
  2052. default:;
  2053. }
  2054. //----------------------
  2055. // error occurred while pushing the raised error into the queue
  2056. if( errCode == 0 )
  2057. {
  2058. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  2059. }
  2060. //----------------------
  2061. return 0;
  2062. }
  2063. /*
  2064. unsigned int CheckCompatibilePorts( ESTATE state, EPORT port )
  2065. {
  2066. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòîâ è ñîñòîÿíèé âîîáùå
  2067. if( !( ( state == eSTATE_SHORT ||
  2068. state == eSTATE_LOAD ||
  2069. state == eSTATE_OPEN ||
  2070. state == eSTATE_LOAD2 ||
  2071. state == eSTATE_OPEN2 ||
  2072. state == eSTATE_T11 ||
  2073. state == eSTATE_T12 ||
  2074. state == eSTATE_T21 ||
  2075. state == eSTATE_T22 ||
  2076. state == eSTATE_A11 ||
  2077. state == eSTATE_A12 ||
  2078. state == eSTATE_A21 ||
  2079. state == eSTATE_A22
  2080. )
  2081. &&
  2082. ( port == ePORT_A ||
  2083. port == ePORT_B ||
  2084. port == ePORT_AB
  2085. )
  2086. )
  2087. ) return FALSE;
  2088. //---------------------------------------------------------------------------------------------------------------------------------------
  2089. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòà (A/B) äëÿ ñîñîòîÿíèÿ SH/LD/OP/OP2/LD2
  2090. if( ( ( state == eSTATE_SHORT ||
  2091. state == eSTATE_LOAD ||
  2092. state == eSTATE_OPEN ||
  2093. state == eSTATE_LOAD2 ||
  2094. state == eSTATE_OPEN2
  2095. )
  2096. &&
  2097. ( port != ePORT_A &&
  2098. port != ePORT_B
  2099. )
  2100. )
  2101. ) return FALSE;
  2102. //---------------------------------------------------------------------------------------------------------------------------------------
  2103. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòà (AB) äëÿ ñîñîòîÿíèÿ T11/T12/T21/T22/A11/A12/A21/A22
  2104. if( ( ( state == eSTATE_T11 ||
  2105. state == eSTATE_T12 ||
  2106. state == eSTATE_T21 ||
  2107. state == eSTATE_T22 ||
  2108. state == eSTATE_A11 ||
  2109. state == eSTATE_A12 ||
  2110. state == eSTATE_A21 ||
  2111. state == eSTATE_A22
  2112. )
  2113. &&
  2114. ( port != ePORT_AB
  2115. )
  2116. )
  2117. ) return FALSE;
  2118. return TRUE;
  2119. }
  2120. unsigned int CheckCompatibilePorts2( ESTATE state, EPORT port ) // using in Path:STATE
  2121. {
  2122. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòîâ è ñîñòîÿíèé âîîáùå
  2123. if( !( ( state == eSTATE_SHORT ||
  2124. state == eSTATE_LOAD ||
  2125. state == eSTATE_OPEN ||
  2126. state == eSTATE_LOAD2 ||
  2127. state == eSTATE_OPEN2 ||
  2128. state == eSTATE_THRU ||
  2129. state == eSTATE_ATTEN
  2130. )
  2131. &&
  2132. ( port == ePORT_A ||
  2133. port == ePORT_B ||
  2134. port == ePORT_AB
  2135. )
  2136. )
  2137. ) return FALSE;
  2138. //---------------------------------------------------------------------------------------------------------------------------------------
  2139. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòà (A/B) äëÿ ñîñîòîÿíèÿ SH/LD/OP/OP2/LD2
  2140. if( ( ( state == eSTATE_SHORT ||
  2141. state == eSTATE_LOAD ||
  2142. state == eSTATE_OPEN ||
  2143. state == eSTATE_LOAD2 ||
  2144. state == eSTATE_OPEN2
  2145. )
  2146. &&
  2147. ( port != ePORT_A &&
  2148. port != ePORT_B
  2149. )
  2150. )
  2151. ) return FALSE;
  2152. //---------------------------------------------------------------------------------------------------------------------------------------
  2153. // ïðîâåðêà ïðàâèëüíîñòè óêàçàíèÿ ïîðòà (AB) äëÿ ñîñîòîÿíèÿ T11/T12/T21/T22/A11/A12/A21/A22
  2154. if( ( state == eSTATE_THRU ||
  2155. state == eSTATE_ATTEN
  2156. )
  2157. &&
  2158. ( port != ePORT_AB
  2159. )
  2160. )
  2161. return FALSE;
  2162. return TRUE;
  2163. }
  2164. */
  2165. unsigned int GPIBInit( USB_DEVICE_INFO * udi )
  2166. {
  2167. _ESE = 0x00;
  2168. _SRE = 0x00;
  2169. // Standard Event Status Register (ESR): bit Power On
  2170. // 27/08/18
  2171. // Note: in this implementation this bit is disabled
  2172. // GPIB_SET_PWN();
  2173. // GPIB_SET_OPC();
  2174. return 0;
  2175. }
  2176. #endif